예제 #1
0
//
// Selects objects within the user defined area, then process them
// 
MStatus meshRemapTool::doRelease( MEvent & event )
{
	char buf[1024];

	// Perform the base actions
	MStatus stat = MPxSelectionContext::doRelease(event);

	// Get the list of selected items 
	MGlobal::getActiveSelectionList( fSelectionList );

	//
	//  If there's nothing selected, don't worry about it, just return
	//
	if( fSelectionList.length() != 1 )
	{
		MGlobal::displayWarning( "Components must be selected one at a time" );
		return MS::kSuccess;
	}

	//
	//  Get the selection's details, we must have exactly one component selected
	//
	MObject component;
	MDagPath path;

	MItSelectionList selectionIt (fSelectionList, MFn::kComponent);

	MStringArray	selections;
	selectionIt.getStrings( selections );
	
	if( selections.length() != 1 )
	{
		MGlobal::displayError( "Components must be selected one at a time" );
		return MS::kSuccess;
	}

	if (selectionIt.isDone ())
	{
		MGlobal::displayError( "Selected Item not a component" );
		return MS::kSuccess;
	}

	if( selectionIt.getDagPath (path, component) != MStatus::kSuccess )
	{
		MGlobal::displayError( "Can't get path for selection");
		return MS::kSuccess;
	}

	if (!path.node().hasFn(MFn::kMesh) && !(path.node().hasFn(MFn::kTransform) && path.hasFn(MFn::kMesh)))
	{
		MGlobal::displayError( " Invalid type! Only a mesh or its transform can be specified." );
		return MS::kSuccess;
	}

	MItMeshVertex fIt ( path, component, &stat );
	if( stat != MStatus::kSuccess )
	{
		MGlobal::displayError( " MItMeshVertex failed");
		return MStatus::kFailure;
	}

	if (fIt.count() != 1 )
	{
		sprintf(buf, " Invalid selection '%s'. Vertices must be picked one at a time.", selections[0].asChar() );
		MGlobal::displayError( buf );
		return MS::kSuccess;
	}
	else
	{
		sprintf(buf, "Accepting vertex '%s'", selections[0].asChar() );
		MGlobal::displayInfo(  buf );
	}

	//
	// Now that we know it's valid, process the selection, the first 3 items are the source, the second
	// 3 define the target
	//

	if( fNumSelectedPoints < 3 )
	{
		fSelectedPathSrc.append( path );
		fSelectedComponentSrc.append( component );
	}
	else 
	{
		fSelectedPathDst.append( path );
		fSelectedComponentDst.append( component );
	}

	//
	//  When each of the source/target are defined, process them. An error/invalid selection will restart the selection for
	//  that particular mesh.
	//  
	if( fNumSelectedPoints == 2 )
	{
		if( ( stat = meshMapUtils::validateFaceSelection( fSelectedPathSrc, fSelectedComponentSrc, &fSelectedFaceSrc, &fSelectVtxSrc ) ) != MStatus::kSuccess )
		{
			MGlobal::displayError("Selected vertices don't define a unique face on source mesh");
			reset();
			return stat;
		}
	}

	//
	// Once the target is defined, invoke the command
	//
	if( fNumSelectedPoints == 5 )
	{
		if( ( stat = meshMapUtils::validateFaceSelection( fSelectedPathDst, fSelectedComponentDst, &fSelectedFaceDst, &fSelectVtxDst ) ) != MStatus::kSuccess )
		{
			MGlobal::displayError("Selected vertices don't define a unique face on source mesh");
			reset();
			return stat;
		}

		fCmd = new meshRemapCommand;
		fCmd->setSeedInfo( true, fSelectedPathSrc[0], fSelectedFaceSrc, fSelectVtxSrc[0], fSelectVtxSrc[1] );
		fCmd->setSeedInfo( false, fSelectedPathDst[0], fSelectedFaceDst, fSelectVtxDst[0], fSelectVtxDst[1] );
		fCmd->redoIt();

		//
		// Empty the selection list since the reodering may move the user's current selection on screen
		//
		MSelectionList empty;
		MGlobal::setActiveSelectionList( empty );

		MGlobal::displayInfo( "Mesh remapping complete" );

		// 
		// Start again, get new meshes
		//
		reset();	
	}
	else
	{
		//
		// We don't have all the details yet, just move to the next item
		//
		fNumSelectedPoints++;	
	}

	helpStateHasChanged();

	return stat;
}
예제 #2
0
void maTranslator::getAddAttrCmds(const MObject& node, MStringArray& cmds)
{
	//
	// Run through the node's attributes.
	//
	MFnDependencyNode	nodeFn(node);
	unsigned int		numAttrs = nodeFn.attributeCount();
	unsigned int		i;

	for (i = 0; i < numAttrs; i++)
	{
		//
		// Use the attribute ordering which Maya uses when doing I/O.
		//
		MObject	attr = nodeFn.reorderedAttribute(i);

		//
		// If this attribute has been added since the node was created,
		// then we may want to write out an addAttr statement for it.
		//
		if (nodeFn.isNewAttribute(attr))
		{
			MFnAttribute	attrFn(attr);

			//
			// If the attribute has a parent then ignore it because it will
			// be processed when we process the parent.
			//
			MStatus	status;

			attrFn.parent(&status);

			if (status == MS::kNotFound)
			{
				//
				// If the attribute is a compound, then we can do its entire
				// tree at once.
				//
				MFnCompoundAttribute	cAttrFn(attr, &status);

				if (status)
				{
					MStringArray	newCmds;

					cAttrFn.getAddAttrCmds(newCmds);

					unsigned int	numCommands = newCmds.length();
					unsigned int	c;

					for (c = 0; c < numCommands; c++)
					{
						if (newCmds[c] != "")
							cmds.append(newCmds[c]);
					}
				}
				else
				{
					MString	newCmd = attrFn.getAddAttrCmd();

					if (newCmd != "") cmds.append(newCmd);
				}
			}
		}
	}
}
예제 #3
0
MStatus animImport::reader(	const MFileObject& file,
								const MString& options,
								FileAccessMode mode)
{
	MStatus status = MS::kFailure;

	MString fileName = file.fullName();
#if defined (OSMac_)	
	char fname[MAXPATHLEN];
	strcpy (fname, fileName.asChar());
	ifstream animFile(fname);
#else
	ifstream animFile(fileName.asChar());
#endif
	// 	Parse the options. The options syntax is in the form of
	//	"flag=val;flag1=val;flag2=val"
	//
	MString pasteFlags;
	if (options.length() > 0) {
		//	Set up the flags for the paste command.
		//
		const MString flagTargetTime("targetTime");
		const MString flagTime("time");
		const MString flagCopies("copies");
		const MString flagOption("option");
		const MString flagConnect("connect");

		MString copyValue;
		MString flagValue;
		MString connectValue;
		MString timeValue;

		//	Start parsing.
		//
		MStringArray optionList;
		MStringArray theOption;
		options.split(';', optionList);

		unsigned nOptions = optionList.length();
		for (unsigned i = 0; i < nOptions; i++) {

			theOption.clear();
			optionList[i].split('=', theOption);
			if (theOption.length() < 1) {
				continue;
			}

			if (theOption[0] == flagCopies && theOption.length() > 1) {
				copyValue = theOption[1];;
			} else if (theOption[0] == flagOption && theOption.length() > 1) {
				flagValue = theOption[1];
			} else if (theOption[0] == flagConnect && theOption.length() > 1) {
				if (theOption[1].asInt() != 0) {
					connectValue += theOption[1];
				}
			} else if (theOption[0] == flagTime && theOption.length() > 1) {
				timeValue += theOption[1];
			} 
		}
	
		if (copyValue.length() > 0) {
			pasteFlags += " -copies ";
			pasteFlags += copyValue;
			pasteFlags += " ";
		} 
		if (flagValue.length() > 0) {
			pasteFlags += " -option \"";
			pasteFlags += flagValue;
			pasteFlags += "\" ";
		} 
		if (connectValue.length() > 0) {
			pasteFlags += " -connect ";
			pasteFlags += connectValue;
			pasteFlags += " ";
		} 
		if (timeValue.length() > 0) {
			bool useQuotes = !timeValue.isDouble();
			pasteFlags += " -time ";
			if (useQuotes) pasteFlags += "\"";
			pasteFlags += timeValue;
			if (useQuotes) pasteFlags += "\"";
			pasteFlags += " ";
		} 
	}

	if (mode == kImportAccessMode) {
		status = importAnim(animFile, pasteFlags);
	}

	animFile.close();
	return status;
}
MStatus AlembicExportCommand::doIt(const MArgList &args)
{
  ESS_PROFILE_SCOPE("AlembicExportCommand::doIt");

  MStatus status = MS::kFailure;

  MTime currentAnimStartTime = MAnimControl::animationStartTime(),
        currentAnimEndTime = MAnimControl::animationEndTime(),
        oldCurTime = MAnimControl::currentTime(),
        curMinTime = MAnimControl::minTime(),
        curMaxTime = MAnimControl::maxTime();
  MArgParser argData(syntax(), args, &status);

  if (argData.isFlagSet("help")) {
    // TODO: implement help for this command
    // MGlobal::displayInfo(util::getHelpText());
    return MS::kSuccess;
  }

  unsigned int jobCount = argData.numberOfFlagUses("jobArg");
  MStringArray jobStrings;
  if (jobCount == 0) {
    // TODO: display dialog
    MGlobal::displayError("[ExocortexAlembic] No jobs specified.");
    MPxCommand::setResult(
        "Error caught in AlembicExportCommand::doIt: no job specified");
    return status;
  }
  else {
    // get all of the jobstrings
    for (unsigned int i = 0; i < jobCount; i++) {
      MArgList jobArgList;
      argData.getFlagArgumentList("jobArg", i, jobArgList);
      jobStrings.append(jobArgList.asString(0));
    }
  }

  // create a vector to store the jobs
  std::vector<AlembicWriteJob *> jobPtrs;
  double minFrame = 1000000.0;
  double maxFrame = -1000000.0;
  double maxSteps = 1;
  double maxSubsteps = 1;

  // init the curve accumulators
  AlembicCurveAccumulator::Initialize();

  try {
    // for each job, check the arguments
    bool failure = false;
    for (unsigned int i = 0; i < jobStrings.length(); ++i) {
      double frameIn = 1.0;
      double frameOut = 1.0;
      double frameSteps = 1.0;
      double frameSubSteps = 1.0;
      MString filename;
      bool purepointcache = false;
      bool normals = true;
      bool uvs = true;
      bool facesets = true;
      bool bindpose = true;
      bool dynamictopology = false;
      bool globalspace = false;
      bool withouthierarchy = false;
      bool transformcache = false;
      bool useInitShadGrp = false;
      bool useOgawa = false;  // Later, will need to be changed!

      // Each frames to export can manually be specified via the "frames" parameter.
      // This allow for very specific frames to be exported.
      // In our case (Squeeze Studio) this allow the animator to export only specific subframes.
      // The advantage of exporting specific subframes instead of using the "substep" parameter is that the animator don't have to
      // fix all the flipping occuring in a rig when trying to work with substeps.
      MDoubleArray frames;

      MStringArray objectStrings;
      std::vector<std::string> prefixFilters;
      std::set<std::string> attributes;
      std::vector<std::string> userPrefixFilters;
      std::set<std::string> userAttributes;
      MObjectArray objects;
      std::string search_str, replace_str;

      // process all tokens of the job
      MStringArray tokens;
      jobStrings[i].split(';', tokens);
      for (unsigned int j = 0; j < tokens.length(); j++) {
        MStringArray valuePair;
        tokens[j].split('=', valuePair);
        if (valuePair.length() != 2) {
          MGlobal::displayWarning(
              "[ExocortexAlembic] Skipping invalid token: " + tokens[j]);
          continue;
        }

        const MString &lowerValue = valuePair[0].toLowerCase();
        if (lowerValue == "in") {
          frameIn = valuePair[1].asDouble();
        }
        else if (lowerValue == "out") {
          frameOut = valuePair[1].asDouble();
        }
        else if (lowerValue == "step") {
          frameSteps = valuePair[1].asDouble();
        }
        else if (lowerValue == "substep") {
          frameSubSteps = valuePair[1].asDouble();
        }
        else if (lowerValue == "normals") {
          normals = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "uvs") {
          uvs = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "facesets") {
          facesets = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "bindpose") {
          bindpose = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "purepointcache") {
          purepointcache = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "dynamictopology") {
          dynamictopology = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "globalspace") {
          globalspace = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "withouthierarchy") {
          withouthierarchy = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "transformcache") {
          transformcache = valuePair[1].asInt() != 0;
        }
        else if (lowerValue == "filename") {
          filename = valuePair[1];
        }
        else if (lowerValue == "objects") {
          // try to find each object
          valuePair[1].split(',', objectStrings);
        }
        else if (lowerValue == "useinitshadgrp") {
          useInitShadGrp = valuePair[1].asInt() != 0;
        }

        // search/replace
        else if (lowerValue == "search") {
          search_str = valuePair[1].asChar();
        }
        else if (lowerValue == "replace") {
          replace_str = valuePair[1].asChar();
        }
        else if (lowerValue == "ogawa") {
          useOgawa = valuePair[1].asInt() != 0;
        }
        else if(lowerValue == "frames")
        {
          MStringArray strFrames;
          valuePair[1].split(',', strFrames);
          for(unsigned int i=0;i<strFrames.length();i++)
          {
            double frame = strFrames[i].asDouble();
            frames.append(frame);
          }
        }
        else if (lowerValue == "attrprefixes") {
          splitListArg(valuePair[1], prefixFilters);
        }
        else if (lowerValue == "attrs") {
          splitListArg(valuePair[1], attributes);
        }
        else if (lowerValue == "userattrprefixes") {
          splitListArg(valuePair[1], userPrefixFilters);
        }
        else if (lowerValue == "userattrs") {
          splitListArg(valuePair[1], userAttributes);
        }
        else {
          MGlobal::displayWarning(
              "[ExocortexAlembic] Skipping invalid token: " + tokens[j]);
          continue;
        }
      }

      // now check the object strings
      for (unsigned int k = 0; k < objectStrings.length(); k++) {
        MSelectionList sl;
        MString objectString = objectStrings[k];
        sl.add(objectString);
        MDagPath dag;
        for (unsigned int l = 0; l < sl.length(); l++) {
          sl.getDagPath(l, dag);
          MObject objRef = dag.node();
          if (objRef.isNull()) {
            MGlobal::displayWarning("[ExocortexAlembic] Skipping object '" +
                                    objectStrings[k] + "', not found.");
            break;
          }

          // get all parents
          MObjectArray parents;

          // check if this is a camera
          bool isCamera = false;
          for (unsigned int m = 0; m < dag.childCount(); ++m) {
            MFnDagNode child(dag.child(m));
            MFn::Type ctype = child.object().apiType();
            if (ctype == MFn::kCamera) {
              isCamera = true;
              break;
            }
          }

          if (dag.node().apiType() == MFn::kTransform && !isCamera &&
              !globalspace && !withouthierarchy) {
            MDagPath ppath = dag;
            while (!ppath.node().isNull() && ppath.length() > 0 &&
                   ppath.isValid()) {
              parents.append(ppath.node());
              if (ppath.pop() != MStatus::kSuccess) {
                break;
              }
            }
          }
          else {
            parents.append(dag.node());
          }

          // push all parents in
          while (parents.length() > 0) {
            bool found = false;
            for (unsigned int m = 0; m < objects.length(); m++) {
              if (objects[m] == parents[parents.length() - 1]) {
                found = true;
                break;
              }
            }
            if (!found) {
              objects.append(parents[parents.length() - 1]);
            }
            parents.remove(parents.length() - 1);
          }

          // check all of the shapes below
          if (!transformcache) {
            sl.getDagPath(l, dag);
            for (unsigned int m = 0; m < dag.childCount(); m++) {
              MFnDagNode child(dag.child(m));
              if (child.isIntermediateObject()) {
                continue;
              }
              objects.append(child.object());
            }
          }
        }
      }

      // check if we have incompatible subframes
      if (maxSubsteps > 1.0 && frameSubSteps > 1.0) {
        const double part = (frameSubSteps > maxSubsteps)
                                ? (frameSubSteps / maxSubsteps)
                                : (maxSubsteps / frameSubSteps);
        if (abs(part - floor(part)) > 0.001) {
          MString frameSubStepsStr, maxSubstepsStr;
          frameSubStepsStr.set(frameSubSteps);
          maxSubstepsStr.set(maxSubsteps);
          MGlobal::displayError(
              "[ExocortexAlembic] You cannot combine substeps " +
              frameSubStepsStr + " and " + maxSubstepsStr +
              " in one export. Aborting.");
          return MStatus::kInvalidParameter;
        }
      }

      // remember the min and max values for the frames
      if (frameIn < minFrame) {
        minFrame = frameIn;
      }
      if (frameOut > maxFrame) {
        maxFrame = frameOut;
      }
      if (frameSteps > maxSteps) {
        maxSteps = frameSteps;
      }
      if (frameSteps > 1.0) {
        frameSubSteps = 1.0;
      }
      if (frameSubSteps > maxSubsteps) {
        maxSubsteps = frameSubSteps;
      }

      // check if we have a filename
      if (filename.length() == 0) {
        MGlobal::displayError("[ExocortexAlembic] No filename specified.");
        for (size_t k = 0; k < jobPtrs.size(); k++) {
          delete (jobPtrs[k]);
        }
        MPxCommand::setResult(
            "Error caught in AlembicExportCommand::doIt: no filename "
            "specified");
        return MStatus::kFailure;
      }

      // construct the frames if they are not already provided
      if (frames.length() == 0)
      {
        const double frameIncr = frameSteps / frameSubSteps;
        for (double frame = frameIn; frame <= frameOut; frame += frameIncr) {
          frames.append(frame);
        }
      }

      AlembicWriteJob *job =
          new AlembicWriteJob(filename, objects, frames, useOgawa,
              prefixFilters, attributes, userPrefixFilters, userAttributes);
      job->SetOption("exportNormals", normals ? "1" : "0");
      job->SetOption("exportUVs", uvs ? "1" : "0");
      job->SetOption("exportFaceSets", facesets ? "1" : "0");
      job->SetOption("exportInitShadGrp", useInitShadGrp ? "1" : "0");
      job->SetOption("exportBindPose", bindpose ? "1" : "0");
      job->SetOption("exportPurePointCache", purepointcache ? "1" : "0");
      job->SetOption("exportDynamicTopology", dynamictopology ? "1" : "0");
      job->SetOption("indexedNormals", "1");
      job->SetOption("indexedUVs", "1");
      job->SetOption("exportInGlobalSpace", globalspace ? "1" : "0");
      job->SetOption("flattenHierarchy", withouthierarchy ? "1" : "0");
      job->SetOption("transformCache", transformcache ? "1" : "0");

      // check if the search/replace strings are valid!
      if (search_str.length() ? !replace_str.length()
                              : replace_str.length())  // either search or
                                                       // replace string is
                                                       // missing or empty!
      {
        ESS_LOG_WARNING(
            "Missing search or replace parameter. No strings will be "
            "replaced.");
        job->replacer = SearchReplace::createReplacer();
      }
      else {
        job->replacer = SearchReplace::createReplacer(search_str, replace_str);
      }

      // check if the job is satifsied
      if (job->PreProcess() != MStatus::kSuccess) {
        MGlobal::displayError("[ExocortexAlembic] Job skipped. Not satisfied.");
        delete (job);
        failure = true;
        break;
      }

      // push the job to our registry
      MGlobal::displayInfo("[ExocortexAlembic] Using WriteJob:" +
                           jobStrings[i]);
      jobPtrs.push_back(job);
    }

    if (failure) {
      for (size_t k = 0; k < jobPtrs.size(); k++) {
        delete (jobPtrs[k]);
      }
      return MS::kFailure;
    }

    // compute the job count
    unsigned int jobFrameCount = 0;
    for (size_t i = 0; i < jobPtrs.size(); i++)
      jobFrameCount += (unsigned int)jobPtrs[i]->GetNbObjects() *
                       (unsigned int)jobPtrs[i]->GetFrames().size();

    // now, let's run through all frames, and process the jobs
    const double frameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit());
    const double incrSteps = maxSteps / maxSubsteps;
    double frame;
    double nextFrame = minFrame + incrSteps;

    /*
    for (double frame = minFrame; frame <= maxFrame;
         frame += incrSteps, nextFrame += incrSteps) {
      MAnimControl::setCurrentTime(MTime(frame / frameRate, MTime::kSeconds));
      MAnimControl::setAnimationEndTime(
          MTime(nextFrame / frameRate, MTime::kSeconds));
      MAnimControl::playForward();  // this way, it forces Maya to play exactly
      // one frame! and particles are updated!

      AlembicCurveAccumulator::StartRecordingFrame();
      for (size_t i = 0; i < jobPtrs.size(); i++) {
        MStatus status = jobPtrs[i]->Process(frame);
        if (status != MStatus::kSuccess) {
          MGlobal::displayError("[ExocortexAlembic] Job aborted :" +
                                jobPtrs[i]->GetFileName());
          for (size_t k = 0; k < jobPtrs.size(); k++) {
            delete (jobPtrs[k]);
          }
          restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                         curMinTime, curMaxTime);
          return status;
        }
      }
      AlembicCurveAccumulator::StopRecordingFrame();
    }
    */
    // Collect all job frames
    std::vector<double> all_frames;
    for(size_t i=0;i<jobPtrs.size();i++)
    {
      const std::vector<double> jobFrames = jobPtrs[i]->GetFrames();
      for (unsigned int j=0;j<jobFrames.size();++j)
      {
        all_frames.push_back(jobFrames[j]);
      }
    }

    // Force Maya to play the animation in sequence. This way particles are updated.
    unsigned int num_frames_to_export = all_frames.size();
    all_frames.push_back(all_frames[num_frames_to_export -1] + incrSteps);
    for (unsigned int i=0;i<num_frames_to_export;++i)
    {
      frame = all_frames[i];
      nextFrame = all_frames[i+1];

      // debuging
      MString msg = "Exporting frame ";
      msg += frame;
      msg += ". Next is ";
      msg += nextFrame;
      MGlobal::displayInfo(msg);

      MAnimControl::setCurrentTime(MTime(frame/frameRate,MTime::kSeconds));
      MAnimControl::setAnimationEndTime( MTime(nextFrame/frameRate,MTime::kSeconds) );
      MAnimControl::playForward();  // this way, it forces Maya to play exactly one frame! and particles are updated!

      AlembicCurveAccumulator::StartRecordingFrame();
      for(size_t i=0;i<jobPtrs.size();i++)
      {
        MStatus status = jobPtrs[i]->Process(frame);
        if(status != MStatus::kSuccess)
        {
          MGlobal::displayError("[ExocortexAlembic] Job aborted :"+jobPtrs[i]->GetFileName());
          for(size_t k=0;k<jobPtrs.size();k++)
          {
            delete(jobPtrs[k]);
          }

          restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime);
          return status;
        }

      }
      AlembicCurveAccumulator::StopRecordingFrame();
    }
  }
  catch (...) {
    MGlobal::displayError(
        "[ExocortexAlembic] Jobs aborted, force closing all archives!");
    for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin();
         beg != jobPtrs.end(); ++beg) {
      (*beg)->forceCloseArchive();
    }
    restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                   curMinTime, curMaxTime);
    MPxCommand::setResult("Error caught in AlembicExportCommand::doIt");
    status = MS::kFailure;
  }
  MAnimControl::stop();
  AlembicCurveAccumulator::Destroy();

  // restore the animation start/end time and the current time!
  restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime,
                 curMinTime, curMaxTime);

  // delete all jobs
  for (size_t k = 0; k < jobPtrs.size(); k++) {
    delete (jobPtrs[k]);
  }

  // remove all known archives
  deleteAllArchives();
  return status;
}
예제 #5
0
// Custom parsing to support array argument. Not using MSyntax.
MStatus skinClusterWeights::parseArgs( const MArgList& args )
{
    MStatus	    status = MS::kSuccess;
    MObject         node;
    MDagPath        dagPath;
    MSelectionList  selList;
    
    editUsed  = true;
    queryUsed = false;
    unsigned int i, nth = 0;
    unsigned int numArgs = args.length();	
    while(status == MS::kSuccess && nth < numArgs-1) {
	MString inputString = args.asString(nth, &status);

	if (status != MS::kSuccess) {
	    MGlobal::displayError("skinClusterWeights syntax error");
	    return status;
	}
      
	if (inputString == kEditFlag || inputString == kEditFlagLong) {
	    editUsed  = true;
	    queryUsed = false;
	    nth++;
	    continue;
	}
      
	if (inputString == kQueryFlag || inputString == kQueryFlagLong) {
	    queryUsed = true;
	    editUsed  = false;
	    nth++;
	    continue;
	}
      
	if (inputString == kInfluenceFlag || inputString == kInfluenceFlagLong) {	    
	    nth++;
	    MStringArray stringArray = args.asStringArray(nth, &status);
	    selList.clear();
	    for (i = 0; i < stringArray.length(); i++) {
	      selList.add(stringArray[i]);
	    }
	    for (i = 0; i < selList.length(); i++) {
	      status = selList.getDagPath(i, dagPath);
	      if (status == MS::kSuccess && dagPath.hasFn(MFn::kTransform)) {
		influenceArray.append(dagPath);
	      } else {
		MGlobal::displayError(inputString + " is not a valid influence object.\n");
		return status;
	      }
	    }
	    nth++;
	    continue;
	}

	if (inputString == kSkinClusterFlag || inputString == kSkinClusterFlagLong) {
	    nth++;
	    MStringArray stringArray = args.asStringArray(nth, &status);
	    selList.clear();
	    for (i = 0; i < stringArray.length(); i++) {
	      selList.add(stringArray[i]);
	    }
	    for (i = 0; i < selList.length(); i++) {
	      status = selList.getDependNode(i, node);
	      if (status == MS::kSuccess && node.hasFn(MFn::kSkinClusterFilter)) {
		skinClusterArray.append(node);
	      } else {
		MGlobal::displayError(inputString + " is not a valid skinCluster.\n");
		return status;
	      }
	    }
	    nth++;
	    continue;
	}

	if (inputString == kWeightFlag || inputString == kWeightFlagLong) {
	    nth++;
	    weightArray = args.asDoubleArray(nth, &status);
	    if (status != MS::kSuccess) {
		MGlobal::displayError("error while parsing weight array");
	    }
	    nth++;
	    continue;
	}

	if (inputString == kAssignAllToSingleFlag || inputString == kAssignAllToSingleFlagLong) {
	    assignAllToSingle = true;
	    nth++;
	    continue;
	}

	MGlobal::displayError("invalid command syntax at " + inputString);
	return MS::kFailure;
    }

    // parse command objects
    // nth should equals to numArgs-1 at this point
    geometryArray = args.asStringArray(nth, &status);
    if (status != MS::kSuccess) {
	MGlobal::displayError("Command object invalid");
	return status;
    }

    if (queryUsed) {
	if (assignAllToSingle) {
	    MGlobal::displayWarning("-as/-assignAllToSingle is ignored with query flag");
	}
	if (weightArray.length() > 0) {
	    MGlobal::displayWarning("-w/-weights is ignored with query flag");
	}
    }
    
    return status;
}
예제 #6
0
	void Helper4::addVariableSS(const std::string& param_name_as, const std::string& param_type_as, const std::string& param_name_maya )
	{
		//std::string ss_name(getSurfaceShaderName(m_nodename,m_ss_model));

		asr::ParamArray ss_params;
		{
			std::string param_value;
			const std::string plugName(param_name_maya);

			MString fullPlugName((m_nodename+"."+plugName).c_str());
			int connected = liquidmaya::ShaderMgr::getSingletonPtr()->convertibleConnection(fullPlugName.asChar());
			if(connected ==0)
			{
				if( isType("color", param_type_as) )
				{
					MDoubleArray val; 
					val.setLength(3);
					IfMErrorWarn(MGlobal::executeCommand("getAttr (\""+fullPlugName+"\")", val));

					param_value = m_nodename+"_"+plugName;
					createColor3(m_assembly->colors(), param_value.c_str(), val[0], val[1], val[2]);
				}
				else if( isType("scalar", param_type_as) )
				{
					MDoubleArray val; 
					val.setLength(3);
					IfMErrorWarn(MGlobal::executeCommand("getAttr (\""+fullPlugName+"\")", val));

					//val contains (r,b,g) value, but I only use val[0] for 'scalar'
					MString strVal0;
					strVal0.set(val[0]);
					param_value = strVal0.asChar();
				}
				else if( isType("string", param_type_as))
				{
					MString val;
					IfMErrorWarn(MGlobal::executeCommand("getAttr (\""+fullPlugName+"\")", val));
					param_value = val.asChar();
				}
				else {
					liquidMessage2(messageWarning,"only [color],[scalar],[string] are handled for an unconnected plug in Surface Shader. "
						"the plug of %s is unhandled.", fullPlugName.asChar());
					param_value = "unhandled";
				}
			}
			else if(connected == 1)//the plug is linked in.
			{
				if( isType("texture_instance", param_type_as) )
				{
					MStringArray srcPlug;
					IfMErrorWarn(MGlobal::executeCommand("listConnections -source true -plugs true \""+fullPlugName+"\"", srcPlug));
					assert(srcPlug.length()==1);
					MStringArray src;
					srcPlug[0].split('.',src);
					MString srcNode(src[0]);

					if( is2DTexture(srcNode) || is3DTexture(srcNode) )
					{
						//visitFile(srcNode.asChar());
						param_value = getTextureInstanceName(srcNode.asChar());
					}else{
						liquidMessage2(messageWarning,"only [texture2D],[texture3D] are handled for a texture_instance connected-in plug in Surface Shader."
							"the plug of %s is unhandled.", fullPlugName.asChar());
						param_value = "unhandled";
					}
				}
				else{
					liquidMessage2(messageWarning,"only [texture_instance] is handled for a connected-in plug in Surface Shader."
						"the plug of %s is unhandled.", fullPlugName.asChar());
					param_value = "unhandled";
				}
			}else{
				liquidMessage2(messageWarning,"[%s] is connected out.", fullPlugName.asChar());
			}
			//
			addVariableSS(param_name_as, param_value);
		}
	}
예제 #7
0
	// Load texture data from a texture node
	MStatus Material::loadTexture(MFnDependencyNode* pTexNode,TexOpType& opType,MStringArray& uvsets,ParamList& params)
	{
		Texture tex;
		// Get texture filename
		MString filename, absFilename;
		MRenderUtil::exactFileTextureName(pTexNode->object(),absFilename);
		filename = absFilename.substring(absFilename.rindex('/')+1,absFilename.length()-1);
		MString command = "toNativePath(\"";
		command += absFilename;
		command += "\")";
		MGlobal::executeCommand(command,absFilename);
		tex.absFilename = absFilename;
		tex.filename = filename;
		tex.uvsetIndex = 0;
		tex.uvsetName = "";
		// Set texture operation type
		tex.opType = opType;
		// Get connections to uvCoord attribute of texture node
		MPlugArray texSrcPlugs;
		pTexNode->findPlug("uvCoord").connectedTo(texSrcPlugs,true,false);
		// Get place2dtexture node (if connected)
		MFnDependencyNode* pPlace2dTexNode = NULL;
		for (int j=0; j<texSrcPlugs.length(); j++)
		{
			if (texSrcPlugs[j].node().hasFn(MFn::kPlace2dTexture))
			{
				pPlace2dTexNode = new MFnDependencyNode(texSrcPlugs[j].node());
				continue;
			}
		}
		// Get uvChooser node (if connected)
		MFnDependencyNode* pUvChooserNode = NULL;
		if (pPlace2dTexNode)
		{
			MPlugArray placetexSrcPlugs;
			pPlace2dTexNode->findPlug("uvCoord").connectedTo(placetexSrcPlugs,true,false);
			for (int j=0; j<placetexSrcPlugs.length(); j++)
			{
				if (placetexSrcPlugs[j].node().hasFn(MFn::kUvChooser))
				{
					pUvChooserNode = new MFnDependencyNode(placetexSrcPlugs[j].node());
					continue;
				}
			}
		}
		// Get uvset index
		if (pUvChooserNode)
		{
			bool foundMesh = false;
			bool foundUvset = false;
			MPlug uvsetsPlug = pUvChooserNode->findPlug("uvSets");
			MPlugArray uvsetsSrcPlugs;
			for (int i=0; i<uvsetsPlug.evaluateNumElements() && !foundMesh; i++)
			{
				uvsetsPlug[i].connectedTo(uvsetsSrcPlugs,true,false);
				for (int j=0; j<uvsetsSrcPlugs.length() && !foundMesh; j++)
				{
					if (uvsetsSrcPlugs[j].node().hasFn(MFn::kMesh))
					{
						uvsetsSrcPlugs[j].getValue(tex.uvsetName);
						for (int k=0; k<uvsets.length() && !foundUvset; k++)
						{
							if (uvsets[k] == tex.uvsetName)
							{
								tex.uvsetIndex = k;
								foundUvset = true;
							}
						}
					}
				}
			}
		}
		// Get texture options from Place2dTexture node
		if (pPlace2dTexNode)
		{
			// Get address mode
			//U
			bool wrapU, mirrorU;
			pPlace2dTexNode->findPlug("wrapU").getValue(wrapU);
			pPlace2dTexNode->findPlug("mirrorU").getValue(mirrorU);
			if (mirrorU)
				tex.am_u = TAM_MIRROR;
			else if (wrapU)
				tex.am_u = TAM_WRAP;
			else
				tex.am_u = TAM_CLAMP;
			// V
			bool wrapV,mirrorV;
			pPlace2dTexNode->findPlug("wrapV").getValue(wrapV);
			pPlace2dTexNode->findPlug("mirrorV").getValue(mirrorV);
			if (mirrorV)
				tex.am_v = TAM_MIRROR;
			else if (wrapV)
				tex.am_v = TAM_WRAP;
			else
				tex.am_v = TAM_CLAMP;
			// Get texture scale
			double covU,covV;
			pPlace2dTexNode->findPlug("coverageU").getValue(covU);
			pPlace2dTexNode->findPlug("coverageV").getValue(covV);
			tex.scale_u = covU;
			if (fabs(tex.scale_u) < PRECISION)
				tex.scale_u = 0;
			tex.scale_v = covV;
			if (fabs(tex.scale_v) < PRECISION)
				tex.scale_v = 0;
			// Get texture scroll
			double transU,transV;
			pPlace2dTexNode->findPlug("translateFrameU").getValue(transU);
			pPlace2dTexNode->findPlug("translateFrameV").getValue(transV);
			tex.scroll_u = -0.5 * (covU-1.0)/covU - transU/covU;
			if (fabs(tex.scroll_u) < PRECISION)
				tex.scroll_u = 0;
			tex.scroll_v = 0.5 * (covV-1.0)/covV + transV/covV;
			if (fabs(tex.scroll_v) < PRECISION)
				tex.scroll_v = 0;
			// Get texture rotation
			double rot;
			pPlace2dTexNode->findPlug("rotateFrame").getValue(rot);
			tex.rot = -rot;
			if (fabs(rot) < PRECISION)
				tex.rot = 0;
		}
		// add texture to material texture list
		m_textures.push_back(tex);
		// free up memory
		if (pUvChooserNode)
			delete pUvChooserNode;
		if (pPlace2dTexNode)
			delete pPlace2dTexNode;

		return MS::kSuccess;
	}
예제 #8
0
//
// Selects objects within the user defined area, then process them
// 
MStatus meshRemapTool::doRelease( MEvent & event )
{
	char buf[1024];

	// Perform the base actions
	MStatus stat = MPxSelectionContext::doRelease(event);

	// Get the list of selected items 
	MGlobal::getActiveSelectionList( fSelectionList );

	//
	//  Get the selection's details, we must have exactly one component selected
	//
	MObject component;
	MDagPath path;

	MItSelectionList selectionIt (fSelectionList, MFn::kComponent);

	MStringArray	selections;
	selectionIt.getStrings( selections );
	
	// There are valid cases where only the meshes are selected.
	if( selections.length() == 0 )
	{
		// Handling the case where the user's workflow is
		// 1) select src mesh, select vtx1, vtx2, vtx3 (i.e. fNumSelectedPoints == 0)
		// 2) select dst mesh, select vtx1, vtx2, vtx3 (i.e. fNumSelectedPoints == 3)
		if( fNumSelectedPoints == 0 || fNumSelectedPoints == 3 )
		{
			MItSelectionList selectionDag (fSelectionList, MFn::kDagNode);
			if (!selectionDag.isDone() && selectionDag.getDagPath(path) == MS::kSuccess)
			{
				path.extendToShape();
				// return true there is exactly one mesh selected
				if (path.hasFn(MFn::kMesh))
				{
					selectionDag.next();
					if (selectionDag.isDone())
					{
						//	If this is the destination mesh, make sure that
						//	it doesn't have history.
						if (fNumSelectedPoints == 3)
						{
							return checkForHistory(path);
						}

						return MS::kSuccess;
					}
				}
			}
		}

		// Handling the case where the user is doing the auto remap, i.e.
		// select src mesh, and then dst mesh when fNumSelectedPoints == 0.
		if( fNumSelectedPoints == 0 )
		{
			MItSelectionList selectionDag (fSelectionList, MFn::kDagNode);
			if (!selectionDag.isDone() && selectionDag.getDagPath(path) == MS::kSuccess)
			{
				path.extendToShape();
				// Confirm first selection is a mesh
				if (path.hasFn(MFn::kMesh))
				{
					selectionDag.next();
					if (!selectionDag.isDone() &&
					    selectionDag.getDagPath(path) == MS::kSuccess)
					{
						path.extendToShape();
						// Confirm second selection is a mesh
						if (path.hasFn(MFn::kMesh))
						{
							selectionDag.next();
							// Confirm there are exactly 2 selections
							if (selectionDag.isDone())
							{
								//	Make sure that the destination mesh
								//	doesn't have history.
								return checkForHistory(path);
							}
						}
					}
				}
			}
		}
	}

	if( selections.length() != 1 )
	{
		MGlobal::displayError( "Must select exactly one vertex" );
		return MS::kSuccess;
	}

	if (selectionIt.isDone ())
	{
		MGlobal::displayError( "Selected item not a vertex" );
		return MS::kSuccess;
	}

	if( selectionIt.getDagPath (path, component) != MStatus::kSuccess )
	{
		MGlobal::displayError( "Must select a mesh or its vertex" );
		return MS::kSuccess;
	}

	if (!path.node().hasFn(MFn::kMesh) && !(path.node().hasFn(MFn::kTransform) && path.hasFn(MFn::kMesh)))
	{
		MGlobal::displayError( "Must select a mesh or its transform" );
		return MS::kSuccess;
	}

	//	If this is the first vertex of the destination mesh, make sure that
	//	it doesn't have history.
	if ((fNumSelectedPoints == 3) && (checkForHistory(path) != MS::kSuccess))
	{
		return MS::kSuccess;
	}

	MItMeshVertex fIt ( path, component, &stat );
	if( stat != MStatus::kSuccess )
	{
		MGlobal::displayError( "MItMeshVertex failed");
		return MStatus::kFailure;
	}

	if (fIt.count() != 1 )
	{
		sprintf(buf, "Invalid selection '%s'. Vertices must be picked one at a time.", selections[0].asChar() );
		MGlobal::displayError( buf );
		return MS::kSuccess;
	}
	else
	{
		sprintf(buf, "Accepting vertex '%s'", selections[0].asChar() );
		MGlobal::displayInfo(  buf );
	}

	//
	// Now that we know it's valid, process the selection, the first 3 items are the source, the second
	// 3 define the target
	//

	if( fNumSelectedPoints < 3 )
	{
		fSelectedPathSrc.append( path );
		fSelectedComponentSrc.append( component );
	}
	else 
	{
		fSelectedPathDst.append( path );
		fSelectedComponentDst.append( component );
	}

	//
	//  When each of the source/target are defined, process them. An error/invalid selection will restart the selection for
	//  that particular mesh.
	//  
	if( fNumSelectedPoints == 2 )
	{
		if( ( stat = meshMapUtils::validateFaceSelection( fSelectedPathSrc, fSelectedComponentSrc, &fSelectedFaceSrc, &fSelectVtxSrc ) ) != MStatus::kSuccess )
		{
			MGlobal::displayError("Selected vertices don't define a unique face on source mesh");
			reset();
			return stat;
		}
	}

	//
	// Once the target is defined, invoke the command
	//
	if( fNumSelectedPoints == 5 )
	{
		if( ( stat = meshMapUtils::validateFaceSelection( fSelectedPathDst, fSelectedComponentDst, &fSelectedFaceDst, &fSelectVtxDst ) ) != MStatus::kSuccess )
		{
			MGlobal::displayError("Selected vertices don't define a unique face on destination mesh");
			reset();
			return stat;
		}

		executeCmd();
	}
	else
	{
		//
		// We don't have all the details yet, just move to the next item
		//
		fNumSelectedPoints++;	
	}

	helpStateHasChanged();

	return stat;
}
예제 #9
0
MStatus AlembicNode::compute(const MPlug & plug, MDataBlock & dataBlock)
{
    MStatus status;

    // update the frame number to be imported
    MDataHandle speedHandle = dataBlock.inputValue(mSpeedAttr, &status);
    double speed = speedHandle.asDouble();

    MDataHandle offsetHandle = dataBlock.inputValue(mOffsetAttr, &status);
    double offset = offsetHandle.asDouble();

    MDataHandle timeHandle = dataBlock.inputValue(mTimeAttr, &status);
    MTime t = timeHandle.asTime();
    double inputTime = t.as(MTime::kSeconds);

    double fps = getFPS();

    // scale and offset inputTime.
    inputTime = computeAdjustedTime(inputTime, speed, offset/fps);

    // this should be done only once per file
	if (mFileInitialized == false)
	{
		mFileInitialized = true;

		//Get list of input filenames
		MFnDependencyNode depNode(thisMObject());
		MPlug layerFilesPlug = depNode.findPlug("abc_layerFiles");
		MFnStringArrayData fnSAD( layerFilesPlug.asMObject() );
		MStringArray storedFilenames = fnSAD.array();

		//Legacy support for single-filename input
		if( storedFilenames.length() == 0 )
		{
			MFileObject fileObject;
			MDataHandle dataHandle = dataBlock.inputValue(mAbcFileNameAttr);
			fileObject.setRawFullName(dataHandle.asString());
			MString fileName = fileObject.resolvedFullName();
			storedFilenames.append( fileName );
		}

		std::vector<std::string> abcFilenames;
		for(unsigned int i = 0; i < storedFilenames.length(); i++)
			abcFilenames.push_back( storedFilenames[i].asChar() );

		Alembic::Abc::IArchive archive;
		Alembic::AbcCoreFactory::IFactory factory;
		factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);

		archive = factory.getArchive( abcFilenames );

		if (!archive.valid())
		{
			MString theError = "Error opening these alembic files: ";

			const unsigned int numFilenames = storedFilenames.length();
			for( unsigned int i = 0; i < numFilenames; i++ )
			{
				theError += storedFilenames[ i ];

				if( i != (numFilenames - 1) )
					theError += ", ";
			}

			printError(theError);
		}

		// initialize some flags for plug update
		mSubDInitialized = false;
		mPolyInitialized = false;

		// When an alembic cache will be imported at the first time using
		// AbcImport, we need to set mIncludeFilterAttr (filterHandle) to be
		// mIncludeFilterString for later use. When we save a maya scene(.ma)
		// mIncludeFilterAttr will be saved. Then when we load the saved
		// .ma file, mIncludeFilterString will be set to be mIncludeFilterAttr.
		MDataHandle includeFilterHandle =
						dataBlock.inputValue(mIncludeFilterAttr, &status);
		MString& includeFilterString = includeFilterHandle.asString();

	   if (mIncludeFilterString.length() > 0)
		{
			includeFilterHandle.set(mIncludeFilterString);
			dataBlock.setClean(mIncludeFilterAttr);
		}
		else if (includeFilterString.length() > 0)
		{
			mIncludeFilterString = includeFilterString;
		}

		MDataHandle excludeFilterHandle =
						dataBlock.inputValue(mExcludeFilterAttr, &status);
		MString& excludeFilterString = excludeFilterHandle.asString();

	   if (mExcludeFilterString.length() > 0)
		{
			excludeFilterHandle.set(mExcludeFilterString);
			dataBlock.setClean(mExcludeFilterAttr);
		}
		else if (excludeFilterString.length() > 0)
		{
			mExcludeFilterString = excludeFilterString;
		}


		MFnDependencyNode dep(thisMObject());
		MPlug allSetsPlug = dep.findPlug("allColorSets");
		CreateSceneVisitor visitor(inputTime, !allSetsPlug.isNull(),
			MObject::kNullObj, CreateSceneVisitor::NONE, "",
			mIncludeFilterString, mExcludeFilterString);

		visitor.walk(archive);

		if (visitor.hasSampledData())
		{
			// information retrieved from the hierarchy traversal
			// and given to AlembicNode to provide update
			visitor.getData(mData);
			mData.getFrameRange(mSequenceStartTime, mSequenceEndTime);
			MDataHandle startFrameHandle = dataBlock.inputValue(mStartFrameAttr,
																&status);
			startFrameHandle.set(mSequenceStartTime*fps);
			MDataHandle endFrameHandle = dataBlock.inputValue(mEndFrameAttr,
																&status);
			endFrameHandle.set(mSequenceEndTime*fps);
		}
	}

    // Retime
    MDataHandle cycleHandle = dataBlock.inputValue(mCycleTypeAttr, &status);
    short playType = cycleHandle.asShort();
    inputTime = computeRetime(inputTime, mSequenceStartTime, mSequenceEndTime,
                              playType);

    clamp<double>(mSequenceStartTime, mSequenceEndTime, inputTime);

    // update only when the time lapse is big enough
    if (fabs(inputTime - mCurTime) > 0.00001)
    {
        mOutRead = std::vector<bool>(mOutRead.size(), false);
        mCurTime = inputTime;
    }

    if (plug == mOutPropArrayAttr)
    {

        if (mOutRead[0])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[0] = true;

        unsigned int propSize =
            static_cast<unsigned int>(mData.mPropList.size());

        if (propSize > 0)
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutPropArrayAttr, &status);

            unsigned int outHandleIndex = 0;
            MDataHandle outHandle;

            // for all of the nodes with sampled attributes
            for (unsigned int i = 0; i < propSize; i++)
            {
                // only use the handle if it matches the index.
                // The index wont line up in the sparse case so we
                // can just skip that element.
                if (outArrayHandle.elementIndex() == outHandleIndex++)
                {
                    outHandle = outArrayHandle.outputValue();
                }
                else
                {
                    continue;
                }

                if (mData.mPropList[i].mArray.valid())
                {
                    readProp(mCurTime, mData.mPropList[i].mArray, outHandle);
                }
                else if (mData.mPropList[i].mScalar.valid())
                {
                    // for visibility only
                    if (mData.mPropList[i].mScalar.getName() ==
                        Alembic::AbcGeom::kVisibilityPropertyName)
                    {
                        Alembic::Util::int8_t visVal = 1;
                        mData.mPropList[i].mScalar.get(&visVal,
                            Alembic::Abc::ISampleSelector(mCurTime,
                                Alembic::Abc::ISampleSelector::kNearIndex ));
                        outHandle.setGenericBool(visVal != 0, false);
                    }
                    else
                    {
                        // for all scalar props
                        readProp(mCurTime, mData.mPropList[i].mScalar, outHandle);
                    }
                }
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
        }

    }
    else if (plug == mOutTransOpArrayAttr )
    {
        if (mOutRead[1])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[1] = true;

        unsigned int xformSize =
            static_cast<unsigned int>(mData.mXformList.size());

        if (xformSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutTransOpArrayAttr, &status);

            MPlug arrayPlug(thisMObject(), mOutTransOpArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

            for (unsigned int i = 0; i < xformSize; i++)
            {
                std::vector<double> sampleList;

                if (mData.mIsComplexXform[i])
                {
                    readComplex(mCurTime, mData.mXformList[i], sampleList);
                }
                else
                {
                    Alembic::AbcGeom::XformSample samp;
                    read(mCurTime, mData.mXformList[i], sampleList, samp);
                }

                unsigned int sampleSize = (unsigned int)sampleList.size();

                for (unsigned int j = 0; j < sampleSize; j++)
                {
                    // only use the handle if it matches the index.
                    // The index wont line up in the sparse case so we
                    // can just skip that element.
                    if (outArrayHandle.elementIndex() == outHandleIndex++)
                    {
                        outHandle = outArrayHandle.outputValue(&status);
                    }
                    else
                        continue;

                    outArrayHandle.next();
                    outHandle.set(sampleList[j]);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutLocatorPosScaleArrayAttr )
    {
        if (mOutRead[8])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[8] = true;

        unsigned int locSize =
            static_cast<unsigned int>(mData.mLocList.size());

        if (locSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutLocatorPosScaleArrayAttr, &status);

            MPlug arrayPlug(thisMObject(), mOutLocatorPosScaleArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

            for (unsigned int i = 0; i < locSize; i++)
            {
                std::vector< double > sampleList;
                read(mCurTime, mData.mLocList[i], sampleList);

                unsigned int sampleSize = (unsigned int)sampleList.size();
                for (unsigned int j = 0; j < sampleSize; j++)
                {
                    // only use the handle if it matches the index.
                    // The index wont line up in the sparse case so we
                    // can just skip that element.
                    if (outArrayHandle.elementIndex() == outHandleIndex++)
                    {
                        outHandle = outArrayHandle.outputValue(&status);
                    }
                    else
                        continue;

                    outArrayHandle.next();
                    outHandle.set(sampleList[j]);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutSubDArrayAttr)
    {
        if (mOutRead[2])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutSubDArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[2] = true;

        unsigned int subDSize =
            static_cast<unsigned int>(mData.mSubDList.size());

        if (subDSize > 0)
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutSubDArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < subDSize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kMesh))
                {
                    MFnMesh fnMesh(obj);
                    readSubD(mCurTime, fnMesh, obj, mData.mSubDList[j],
                        mSubDInitialized);
                    outHandle.set(obj);
                }
            }
            mSubDInitialized = true;
            outArrayHandle.setAllClean();
        }
        // for the case where we don't have any nodes, we want to make sure
        // to push out empty meshes on our connections, this can happen if
        // the input file was offlined, currently we only need to do this for
        // meshes as Nurbs, curves, and the other channels don't crash Maya
        else
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutSubDArrayAttr, &status);

            if (outArrayHandle.elementCount() > 0)
            {
                do
                {
                    MDataHandle outHandle = outArrayHandle.outputValue();
                    MObject obj = outHandle.data();
                    if (obj.hasFn(MFn::kMesh))
                    {
                        MFloatPointArray emptyVerts;
                        MIntArray emptyCounts;
                        MIntArray emptyConnects;
                        MFnMesh emptyMesh;
                        emptyMesh.create(0, 0, emptyVerts, emptyCounts,
                            emptyConnects, obj);
                        outHandle.set(obj);
                    }
                }
                while (outArrayHandle.next() == MS::kSuccess);
            }
            mSubDInitialized = true;
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutPolyArrayAttr)
    {
        if (mOutRead[3])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutPolyArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[3] = true;

        unsigned int polySize =
            static_cast<unsigned int>(mData.mPolyMeshList.size());

        if (polySize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutPolyArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < polySize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kMesh))
                {
                    MFnMesh fnMesh(obj);
                    readPoly(mCurTime, fnMesh, obj, mData.mPolyMeshList[j],
                        mPolyInitialized);
                    outHandle.set(obj);
                }
            }
            mPolyInitialized = true;
            outArrayHandle.setAllClean();
        }
        // for the case where we don't have any nodes, we want to make sure
        // to push out empty meshes on our connections, this can happen if
        // the input file was offlined, currently we only need to do this for
        // meshes as Nurbs, curves, and the other channels don't crash Maya
        else
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutPolyArrayAttr, &status);

            if (outArrayHandle.elementCount() > 0)
            {
                do
                {
                    MDataHandle outHandle = outArrayHandle.outputValue(&status);
                    MObject obj = outHandle.data();
                    if (obj.hasFn(MFn::kMesh))
                    {
                        MFloatPointArray emptyVerts;
                        MIntArray emptyCounts;
                        MIntArray emptyConnects;
                        MFnMesh emptyMesh;
                        emptyMesh.create(0, 0, emptyVerts, emptyCounts,
                            emptyConnects, obj);
                        outHandle.set(obj);
                    }
                }
                while (outArrayHandle.next() == MS::kSuccess);
            }
            mPolyInitialized = true;
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutCameraArrayAttr)
    {
        if (mOutRead[4])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[4] = true;

        unsigned int cameraSize =
            static_cast<unsigned int>(mData.mCameraList.size());

        if (cameraSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutCameraArrayAttr, &status);
            MPlug arrayPlug(thisMObject(), mOutCameraArrayAttr);
            double angleConversion = 1.0;

            switch (MAngle::uiUnit())
            {
                case MAngle::kRadians:
                    angleConversion = 0.017453292519943295;
                break;
                case MAngle::kAngMinutes:
                    angleConversion = 60.0;
                break;
                case MAngle::kAngSeconds:
                    angleConversion = 3600.0;
                break;
                default:
                break;
            }

            MDataHandle outHandle;
            unsigned int index = 0;

            for (unsigned int cameraIndex = 0; cameraIndex < cameraSize;
                cameraIndex++)
            {
                Alembic::AbcGeom::ICamera & cam =
                    mData.mCameraList[cameraIndex];
                std::vector<double> array;

                read(mCurTime, cam, array);

                for (unsigned int dataIndex = 0; dataIndex < array.size();
                    dataIndex++, index++)
                {
                    // skip over sparse elements
                    if (index != outArrayHandle.elementIndex())
                    {
                        continue;
                    }

                    outHandle = outArrayHandle.outputValue(&status);
                    outArrayHandle.next();

                    // not shutter angle index, so not an angle
                    if (dataIndex != 11)
                    {
                        outHandle.set(array[dataIndex]);
                    }
                    else
                    {
                        outHandle.set(array[dataIndex] * angleConversion);
                    }
                }  // for the per camera data handles
            }  // for each camera
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutNurbsSurfaceArrayAttr)
    {
        if (mOutRead[5])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[5] = true;

        unsigned int nSurfaceSize =
            static_cast<unsigned int>(mData.mNurbsList.size());

        if (nSurfaceSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < nSurfaceSize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                    continue;

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kNurbsSurface))
                {
                    readNurbs(mCurTime, mData.mNurbsList[j], obj);
                    outHandle.set(obj);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutNurbsCurveGrpArrayAttr)
    {
        if (mOutRead[6])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[6] = true;

        unsigned int nCurveGrpSize =
            static_cast<unsigned int>(mData.mCurvesList.size());

        if (nCurveGrpSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status);
            MDataHandle outHandle;

            std::vector<MObject> curvesObj;
            for (unsigned int i = 0; i < nCurveGrpSize; ++i)
            {
                readCurves(mCurTime, mData.mCurvesList[i],
                    mData.mNumCurves[i], curvesObj);
            }

            std::size_t numChild = curvesObj.size();

            // not the best way to do this
            // only reading bunches of curves based on the connections would be
            // more efficient when there is a bunch of broken connections
            for (unsigned int i = 0; i < numChild; i++)
            {
                if (outArrayHandle.elementIndex() != i)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();
                status = outHandle.set(curvesObj[i]);
            }

            outArrayHandle.setAllClean();
        }
    }
    else
    {
        return MS::kUnknownParameter;
    }

    dataBlock.setClean(plug);
    return status;
}
예제 #10
0
MStatus rtgTranslator::writer ( const MFileObject & fileObject,
								  const MString & options,
								  MPxFileTranslator::FileAccessMode mode)
{
	char            LTmpStr[MAXPATHLEN];
	unsigned int	i;
	int             LN;

	const MString   fname = fileObject.fullName ();
	MString         extension;
	MString         baseFileName;

    int             TimeSlider = 0;
    int             AnimEnabled = 0;


	// Lets strip off the known extension of .rtg if it is there.
	
	extension.set (".rtg");
	int  extLocation = fileObject.name ().rindex ('.');

	if (extLocation > 0 && fileObject.name ().substring (extLocation,
			     fileObject.name ().length () - 1) == extension)
	{
		baseFileName = fileObject.name ().substring (0, extLocation - 1);
	} else
	{
		baseFileName = fileObject.name ();
		extension.clear ();
	}


    DtExt_SceneInit( (char *)baseFileName.asChar() );
	
	// Lets now do all of the option processing
	
	if (options.length () > 0)
	{
		//Start parsing.

		MStringArray optionList;
		MStringArray    theOption;

		options.split (';', optionList);

		//break out all the options.

		for ( i = 0; i < optionList.length (); ++i)
		{
			theOption.clear ();
			optionList[i].split ('=', theOption);
			if (theOption.length () > 1)
			{
				if (theOption[0] == MString ("v18compatible"))
				{
					rtg_v18_compatible = (int) (theOption[1].asInt() );
					
				} else if (theOption[0] == MString ("timeslider"))
				{
					TimeSlider = (int) (theOption[1].asInt ());
                } else if (theOption[0] == MString ("animEnabled"))
                {
                    AnimEnabled = (int) (theOption[1].asInt ());

				} else if (theOption[0] == MString ("animStart"))
				{
                    DtFrameSetStart( (int) (theOption[1].asInt ()) );

				} else if (theOption[0] == MString ("animEnd"))
				{
                    DtFrameSetEnd( (int) (theOption[1].asInt ()) );

				} else if (theOption[0] == MString ("animStep"))
				{
                    DtFrameSetBy( (int) (theOption[1].asInt ()) );

				} else if (theOption[0] == MString ("hrcType"))
				{
                    switch ( theOption[1].asInt () - 1)
                    {
                        case VRHRC_FLAT:
                            DtExt_setOutputTransforms (kTRANSFORMMINIMAL);
                            DtExt_setParents (0);
                            break;
                            
                        case VRHRC_WORLD:
                            DtExt_setOutputTransforms (kTRANSFORMNONE);
                            DtExt_setParents (0);
                            break;
                            
                        case VRHRC_FULL:
                        default:
                            DtExt_setOutputTransforms (kTRANSFORMALL);
                            DtExt_setParents (1);
                            break;
                    }       

                } else if (theOption[0] == MString ("joints"))
                { 
                    // Allow user to specify if the hierarchy should include
					// NULL geometry nodes - usually joints 
                    
                    DtExt_setJointHierarchy( theOption[1].asInt() );
 
				} else if (theOption[0] == MString ("exportSel"))
				{
                    switch ( theOption[1].asInt () - 1)
                    {
                        case VRSEL_ALL:
                            DtExt_setWalkMode (ALL_Nodes);
                            break;
                        case VRSEL_ACTIVE:
                            DtExt_setWalkMode (ACTIVE_Nodes);
                            break;
                        case VRSEL_PICKED:
                            DtExt_setWalkMode (PICKED_Nodes);
                            break;
                    }      
				} else if (theOption[0] == MString ("texsample"))
				{
                    // Allow user to specify if the textures should be sampled 
                    // with the Texture Placement options
                    
                    DtExt_setSoftTextures ( theOption[1].asInt() );

				} else if (theOption[0] == MString ("texevaluate"))
				{
                    // Allow the user to specify if the tex should be eval with
                    // convertSolidTx command or read in if is a file texture.
                    
                    DtExt_setInlineTextures( theOption[1].asInt() );

				} else if (theOption[0] == MString ("texoriginal"))
				{
                    // Allow the user to specify if the tex should be eval at all.
                    
                    DtExt_setOriginalTexture( theOption[1].asInt() );
					
				} else if (theOption[0] == MString ("Xtexres"))
				{
                    // Set the X size of the texture swatches to use  
                    
                    DtExt_setXTextureRes ( theOption[1].asInt () );

				} else if (theOption[0] == MString ("Ytexres"))
				{
                    // Set the Y size of the texture swatches to use  
                    DtExt_setYTextureRes ( theOption[1].asInt () );

				} else if (theOption[0] == MString ("MaxXtexres"))
				{
                    // Set the Max X size of the texture swatches to use  
                    DtExt_setMaxXTextureRes( theOption[1].asInt () );
                
				} else if (theOption[0] == MString ("MaxYtexres"))
				{
                    // Set the Max Y size of the texture swatches to use  
                    DtExt_setMaxYTextureRes( theOption[1].asInt () );

				} else if (theOption[0] == MString ("precision"))
				{
					//VR_Precision = theOption[1].asInt ();
				} else if (theOption[0] == MString ("verbose"))
				{
                   // DtExt_setDebug ( theOption[1].asInt () );

                } else if (theOption[0] == MString ("debug"))
                { 
                    int levelG = DtExt_Debug();
                    if ( (int) (theOption[1].asInt () ) )
                        levelG |= DEBUG_GEOMAT;
                    else 
                        levelG &= ~DEBUG_GEOMAT;
                        
                    DtExt_setDebug( levelG );
                    
                } else if (theOption[0] == MString ("debugC"))
                { 
                    int levelC = DtExt_Debug();
                    if ( (int) (theOption[1].asInt () ) )
                        levelC |= DEBUG_CAMERA;
                    else 
                        levelC &= ~DEBUG_CAMERA;
                        
                    DtExt_setDebug( levelC );
                    
                } else if (theOption[0] == MString ("debugL"))
                { 
                    int levelL = DtExt_Debug();
                    if ( (int) (theOption[1].asInt () ) )
                        levelL |= DEBUG_LIGHT;
                    else 
                        levelL &= ~DEBUG_LIGHT;
                        
                    DtExt_setDebug( levelL );

				} else if (theOption[0] == MString ("reversed"))
				{
					DtExt_setWinding( theOption[1].asInt() );

				} else if (theOption[0] == MString ("tesselation"))
				{
					if ( theOption[1].asInt() == 2 )
					{
						DtExt_setTesselate( kTESSQUAD );
					} else {
						DtExt_setTesselate( kTESSTRI );
					}

				//
				// Now come the translator specific options
				//

                } else if (theOption[0] == MString ("imageformat"))
                {
					rtg_output_image_format = theOption[1].asInt();

                } else if (theOption[0] == MString ("fileformat"))
                {
                    rtg_output_file_format = theOption[1].asInt();

                } else if (theOption[0] == MString ("vnormals"))
                { 
                    rtg_output_vert_norms = theOption[1].asInt();

                } else if (theOption[0] == MString ("vcolors"))
                { 
                    rtg_output_vert_colors = theOption[1].asInt();

                } else if (theOption[0] == MString ("tcoords"))
                { 
                    rtg_output_tex_coords = theOption[1].asInt();

                } else if (theOption[0] == MString ("pnormals"))
                { 
                    rtg_output_poly_norms = theOption[1].asInt();

                } else if (theOption[0] == MString ("idxcnt"))
                { 
                    rtg_show_index_counters = theOption[1].asInt();

                } else if (theOption[0] == MString ("anglesdeg"))
                { 
                    rtg_output_degrees = theOption[1].asInt();

                } else if (theOption[0] == MString ("materials"))
                { 
                    rtg_output_materials = theOption[1].asInt();

                } else if (theOption[0] == MString ("multitexture"))
                {
                    DtExt_setMultiTexture( theOption[1].asInt() );

                } else if (theOption[0] == MString ("mdecomp"))
                { 
                    rtg_output_decomp = theOption[1].asInt();

                } else if (theOption[0] == MString ("pivoth"))
                { 
                    rtg_output_pivots = theOption[1].asInt();

                } else if (theOption[0] == MString ("transforms"))
                { 
                    rtg_output_transforms = theOption[1].asInt();

                } else if (theOption[0] == MString ("ltransforms"))
                { 
                    rtg_output_local = theOption[1].asInt();

                } else if (theOption[0] == MString ("animation"))
                { 
                    rtg_output_animation = theOption[1].asInt();

                } else if (theOption[0] == MString ("allnodes"))
                { 
                    rtg_output_all_nodes = theOption[1].asInt();

                } else if (theOption[0] == MString ("script"))
                {
                    scriptToRun = theOption[1];

                } else if (theOption[0] == MString ("scriptAppend"))
                {
                    scriptAppend = (int)(theOption[1].asInt() );
                }

			}
		}
	}

	// Lets see how we entered this plug-in, either with the export all
	// or export selection flag set.

    if ( mode == MPxFileTranslator::kExportActiveAccessMode )
	{ 
        DtExt_setWalkMode ( ACTIVE_Nodes );
	}

    // Lets check the TimeSlider control now:

    if ( TimeSlider )
    {
        MTime start( MAnimControl::minTime().value(), MTime::uiUnit() );
		DtFrameSetStart( (int) start.value() );

        MTime end( MAnimControl::maxTime().value(), MTime::uiUnit() );
		DtFrameSetEnd( (int) end.value() );
    }


    // Now see if the animation is really enabled.
    // Else we will set the end frame to the beginning frame automatically

    if ( !AnimEnabled )
    {
        DtFrameSetEnd( DtFrameGetStart() );
    }

	// Find out where the file is supposed to end up.
	
	MDt_GetPathName ((char *) (fname.asChar ()), LTmpStr, MAXPATHLEN);

	LN = (int)strlen (LTmpStr);
	if (LTmpStr[LN - 1] == '/')
		LTmpStr[LN - 1] = '\0';

	DtSetDirectory (LTmpStr);

    // Now lets setup some paths to do basic texture file searching
    // for those textures with relative paths
    
    MStringArray wSpacePaths;
    MStringArray rPaths;
    MString      usePath;
    MString      separator;
    
    MGlobal::executeCommand( "workspace -q -rd", wSpacePaths );
    MGlobal::executeCommand( "workspace -q -rtl", rPaths );
    
    if ( DtExt_getTextureSearchPath() )
        separator.set( "|" );
    else
        separator.set( "" );
    
    for (i = 0; i < wSpacePaths.length (); ++i)
    {   
        for ( unsigned int j = 0; j < rPaths.length(); j++ )
        {   
            usePath = usePath + separator + wSpacePaths[i] + MString( "/" ) + rPaths[j];    
            separator.set( "|" );
            
            if ( rPaths[j] == MString( "sourceImages" ) )
                usePath = usePath + separator + wSpacePaths[i] + MString( "/" )
                + MString( "sourceimages" );
        
        }
    }
    
    DtExt_addTextureSearchPath( (char *)usePath.asChar() );
    

    // Now we can setup the database from the wire file geometry.
    // This is where all the Maya data are retrieved, cached, and processed.
    //
    
    // Say that we want to have camera info
    
    DtExt_setOutputCameras( 1 );
    
    //Now we can setup the database from the wire file geometry
    
    DtExt_dbInit();
    
	DtFrameSet( DtFrameGetStart() );

    // Now do the export

    rtgExport();
    


    // Now lets see if the user wants something else to be done
    
    if ( 0 < scriptToRun.length() )
    {
        if ( scriptAppend )
        {
            scriptToRun += MString( " " ) + MString( LTmpStr );
        }   
        
        system( scriptToRun.asChar() );
    }   

    // Clean house.
    //
    
    DtExt_CleanUp();

	
	return MS::kSuccess;
}
예제 #11
0
MStatus getLight::readLight(yafaray::yafrayInterface_t &yI)
{
	MStatus stat;

	bool hasYafLight=0;

	MString listPoint("ls -type yafPointLight");
	MStringArray pointResult;
	MGlobal::executeCommand(listPoint, pointResult);
	
	if(pointResult.length()>0)
	{
		    hasYafLight=1;
			for(unsigned int i=0;i<pointResult.length();i++)
			{
				//test output
				cout<<pointResult[i].asChar()<<endl;

				MSelectionList list;
				MGlobal::getSelectionListByName(pointResult[i],list);
				for(unsigned int index=0;index<list.length();index++)
				{
					MDagPath pointPath;
					list.getDagPath(index,pointPath);

					MObject pointTransNode=pointPath.transform();
					MFnTransform pointTrans(pointTransNode);
					MGlobal::displayInfo(pointTrans.name());
					MVector transP=pointTrans.getTranslation(MSpace::kTransform);

					//test output
					//this is the position of the point light
					cout<<"============test light==========="<<endl;
					cout<<transP.x<<transP.y<<transP.z<<endl;

					MObject pointDepNode;
					list.getDependNode(index,pointDepNode);
					MFnDependencyNode pointDepFn(pointDepNode);

					yI.paramsClearAll();
					yI.paramsSetString("type","pointlight");

					yI.paramsSetPoint("from",transP.x,transP.y,transP.z);

					MObject pointColor;
					pointDepFn.findPlug("LightColor").getValue(pointColor);
					MFnNumericData pointData(pointColor);
					float pcR,pcG,pcB;
					pointData.getData(pcR,pcG,pcB);
					yI.paramsSetColor("color",pcR,pcG,pcB);

					float pointPower;
					pointDepFn.findPlug("Power").getValue(pointPower);
					yI.paramsSetFloat("power",pointPower);

					cout<<"================point light=============="<<endl;
					cout<<pointDepFn.name().asChar()<<endl;
					yI.createLight(pointDepFn.name().asChar());

				}

			}
	}

	//sphere light
	MString listSphere("ls -type yafSphereLight");
	MStringArray sphereResult;
	MGlobal::executeCommand(listSphere, sphereResult);

	if(sphereResult.length()>0)
	{
		hasYafLight=1;
		for(unsigned int i=0;i<sphereResult.length();i++)
		{
			//test output
			cout<<sphereResult[i].asChar()<<endl;

			MSelectionList list;
			MGlobal::getSelectionListByName(sphereResult[i],list);
			for(unsigned int index=0;index<list.length();index++)
			{
				MDagPath spherePath;
				list.getDagPath(index,spherePath);

				MObject sphereTransNode=spherePath.transform();
				MFnTransform sphereTrans(sphereTransNode);
				MVector transP=sphereTrans.getTranslation(MSpace::kTransform);

				MFnDagNode sphereFn(spherePath);
				MObject sphereColor;
				sphereFn.findPlug("LightColor").getValue(sphereColor);
				MFnNumericData sphereData(sphereColor);
				float sphereR,sphereG,sphereB;
				sphereData.getData(sphereR,sphereG,sphereB);

				float power;
				sphereFn.findPlug("Power").getValue(power);

				int samples;
				sphereFn.findPlug("Samples").getValue(samples);

				float radius;
				sphereFn.findPlug("Radius").getValue(radius);
				

				//check if draw geometry needed
				bool makeGeo;
				sphereFn.findPlug("MakeGeometry").getValue(makeGeo);
				if (makeGeo)
				{
					int u=24;
					int v=48;

					yI.paramsClearAll();
					yI.paramsSetString("type","light_mat");
					yI.paramsSetFloat("power",power);
					yI.paramsSetColor("color",sphereR,sphereG,sphereB);
					yafaray::material_t *lightMat=yI.createMaterial(sphereFn.name().asChar());

					int sphereID=makeSphere(yI,u,v,transP.x,transP.y,transP.z,radius,lightMat);
					yI.paramsSetInt("object",sphereID);
				}

				yI.paramsClearAll();
				yI.paramsSetString("type","spherelight");
				yI.paramsSetPoint("from",transP.x, transP.y,transP.z);
				yI.paramsSetColor("color",sphereR,sphereG,sphereB);
				yI.paramsSetFloat("power",power);
				yI.paramsSetInt("samples",samples);
				yI.paramsSetFloat("radius",radius);


				cout<<"================sphere light=============="<<endl;
				cout<<sphereFn.name().asChar()<<endl;
				yI.createLight(sphereFn.name().asChar());

			}

		}
	}
	MString listSun("ls -type yafSunLight");
	MStringArray sunResult;
	MGlobal::executeCommand(listSun,sunResult);
	if (sunResult.length()>0)
	{
		hasYafLight=1;
		for (unsigned int i=0;i<sunResult.length();i++)
		{
			//test output
			cout<<sunResult[i].asChar()<<endl;

			MSelectionList list;
			MGlobal::getSelectionListByName(sunResult[i],list);
			for(unsigned int index=0;index<list.length();index++)
			{
				MDagPath sunPath;
				list.getDagPath(index,sunPath);

				MObject sunTransNode=sunPath.transform();
				MFnTransform sunTrans(sunTransNode);
				MTransformationMatrix sunMatrix=sunTrans.transformation();
				MMatrix sMatrix=sunMatrix.asMatrix();
				MVector transP=sunTrans.getTranslation(MSpace::kTransform);

				MPoint direction1(0.0,0.0,0.0);
				MPoint direction2(0.0,0.0,1.0);
				MPoint direction=direction1-direction2;
				direction*=sMatrix;

				yI.paramsClearAll();
				yI.paramsSetString("type","sunlight");
				MFnDagNode sunFn(sunPath);

				yI.paramsSetPoint("from",transP.x, transP.y,transP.z);
				yI.paramsSetPoint("direction",direction.x,direction.y,direction.z);

				MObject sunColor;
				sunFn.findPlug("LightColor").getValue(sunColor);
				MFnNumericData sunData(sunColor);
				float sunR,sunG,sunB;
				sunData.getData(sunR,sunG,sunB);
				yI.paramsSetColor("color",sunR,sunG,sunB);

				float power;
				sunFn.findPlug("Power").getValue(power);
				yI.paramsSetFloat("power",power);

				int samples;
				sunFn.findPlug("Samples").getValue(samples);
				yI.paramsSetInt("samples",samples);

				float angle;
				sunFn.findPlug("Angle").getValue(angle);
				yI.paramsSetFloat("angle",angle);

				cout<<"================sun light=============="<<endl;
				cout<<sunFn.name().asChar()<<endl;
				yI.createLight(sunFn.name().asChar());

			}
		}
	}

	//spot light
	MString listSpot("ls -type yafSpotLight");
	MStringArray spotResult;
	MGlobal::executeCommand(listSpot, spotResult);

	if(spotResult.length()>0)
	{
		hasYafLight=1;
		for(unsigned int i=0;i<spotResult.length();i++)
		{
			//test output
			cout<<spotResult[i].asChar()<<endl;

			MSelectionList list;
			MGlobal::getSelectionListByName(spotResult[i],list);
			for(unsigned int index=0;index<list.length();index++)
			{
				MDagPath spotPath;
				list.getDagPath(index,spotPath);

				MObject spotTransNode=spotPath.transform();
				MFnTransform spotTrans(spotTransNode);
				MTransformationMatrix spotMatrix=spotTrans.transformation();
				MMatrix sMatrix=spotMatrix.asMatrix();
				MVector transP=spotTrans.getTranslation(MSpace::kTransform);

				MPoint direction1(0.0,0.0,0.0);
				MPoint direction2(0.0,-1.0,0.0);
				MPoint direction=direction2-direction1;
				direction*=sMatrix;

				yI.paramsClearAll();
				yI.paramsSetString("type","spotlight");
				MFnDagNode spotFn(spotPath);

				yI.paramsSetPoint("from",transP.x, transP.y,transP.z);
				yI.paramsSetPoint("to",direction.x,direction.y,direction.z);

				MObject spotColor;
				spotFn.findPlug("LightColor").getValue(spotColor);
				MFnNumericData spotData(spotColor);
				float spotR,spotG,spotB;
				spotData.getData(spotR,spotG,spotB);
				yI.paramsSetColor("color",spotR,spotG,spotB);

				float power;
				spotFn.findPlug("Power").getValue(power);
				yI.paramsSetFloat("power",power);

				float coneAngle;
				spotFn.findPlug("ConeAngle").getValue(coneAngle);
				yI.paramsSetFloat("cone_angle",coneAngle);

				float blend;
				spotFn.findPlug("PenumbraDistance").getValue(blend);
				yI.paramsSetFloat("blend",blend);

				bool softShadows;
				spotFn.findPlug("SoftShadows").getValue(softShadows);
				yI.paramsSetBool("soft_shadows",softShadows);

				float fuzzyness;
				spotFn.findPlug("ShadowFuzzyness").getValue(fuzzyness);
				yI.paramsSetFloat("shadowFuzzyness",fuzzyness);

				bool photonOnly;
				spotFn.findPlug("PhotonOnly").getValue(photonOnly);
				yI.paramsSetBool("photon_only",photonOnly);

				int samples;
				spotFn.findPlug("Samples").getValue(samples);
				yI.paramsSetInt("samples",samples);

				cout<<"================spot light=============="<<endl;
				cout<<spotFn.name().asChar()<<endl;
				yI.createLight(spotFn.name().asChar());

			}

		}
	}
	//directional lights
	MString listDirectional("ls -type yafDirectionalLight");
	MStringArray dirResult;
	MGlobal::executeCommand(listDirectional,dirResult);
	if(dirResult.length()>0)
	{
		    hasYafLight=1;

			for (unsigned int i=0; i<dirResult.length(); i++)
			{
				MSelectionList list;
				MGlobal::getSelectionListByName(dirResult[i],list);
				for(unsigned int index=0;index<list.length();index++)
				{
					MDagPath dirShapePath;
					list.getDagPath(index,dirShapePath);
					MFnTransform dirTransform(dirShapePath.transform());
					MTransformationMatrix dirTransMatrix=dirTransform.transformation();
					MMatrix dirMatrix=dirTransMatrix.asMatrix();

					MPoint direction1(0,0,0);
					MPoint direction2(0,0,-1);
					MPoint direction=direction1-direction2;
					direction*=dirMatrix;

					yI.paramsClearAll();
					yI.paramsSetString("type","directional");

					yI.paramsSetPoint("direction",direction.x, direction.y, direction.z);

					MFnDagNode dirShapeFn(dirShapePath);
					MObject dirColor;
					dirShapeFn.findPlug("LightColor").getValue(dirColor);
					MFnNumericData dirData(dirColor);
					float dirR,dirG,dirB;
					dirData.getData(dirR,dirG,dirB);
					yI.paramsSetColor("color",dirR,dirG,dirB);

					float power;
					dirShapeFn.findPlug("Power").getValue(power);
					yI.paramsSetFloat("power",power);

					bool infinite;
					dirShapeFn.findPlug("Infinite").getValue(infinite);
					yI.paramsSetBool("infinite",infinite);

					float radius;
					dirShapeFn.findPlug("Radius").getValue(radius);
					yI.paramsSetFloat("radius",radius);

					MVector dirP=dirTransform.getTranslation(MSpace::kTransform);
					yI.paramsSetPoint("from",dirP.x,dirP.y,dirP.z);

					cout<<"================directional light=============="<<endl;
					cout<<dirShapeFn.name().asChar()<<endl;
					yI.createLight(dirShapeFn.name().asChar());
					
				}
			}
	}

	//area lights
	MString listArea("ls -type yafAreaLight");
	MStringArray areaResult;
	MGlobal::executeCommand(listArea, areaResult);
	if(areaResult.length()>0)
	{
		    hasYafLight=1;

			for(unsigned int i=0;i<areaResult.length();i++)
			{
				MSelectionList list;
				MGlobal::getSelectionListByName(areaResult[i],list);
				for(unsigned int index=0;index<list.length();index++)
				{
					MDagPath areaShapePath;
					list.getDagPath(index,areaShapePath);
					//areaTransform is the transform node of this light, all the location information is here
					MFnTransform areaTransform(areaShapePath.transform());
					MTransformationMatrix areaTransMatrix=areaTransform.transformation();
					MMatrix areaMatrix=areaTransMatrix.asMatrix();
					//this is the shape node of the light, all the attribute is here

					MPoint corner(-1.0,-1.0,0);
					MPoint point1(-1.0,1.0,0);
					MPoint point2(1.0,1.0,0);
					MPoint point3(1.0,-1.0,0);
					corner*=areaMatrix;
					point1*=areaMatrix;
					point2*=areaMatrix;
					point3*=areaMatrix;

					MVector areaP=areaTransform.getTranslation(MSpace::kTransform);

					MFnDagNode areaShapeFn(areaShapePath);
					int samples;
					areaShapeFn.findPlug("Samples").getValue(samples);

					MObject areaColor;
					areaShapeFn.findPlug("LightColor").getValue(areaColor);
					MFnNumericData areaData(areaColor);
					float areaR,areaG,areaB;
					areaData.getData(areaR,areaG,areaB);

					float power;
					areaShapeFn.findPlug("Power").getValue(power);

					bool makeGeo;
					areaShapeFn.findPlug("MakeGeometry").getValue(makeGeo);
					if (makeGeo==1)
					{
						//create light
						yI.paramsClearAll();
						yI.paramsSetString("type","light_mat");
						yI.paramsSetFloat("power",power);
						yI.paramsSetColor("color",areaR,areaG,areaB);
						yafaray::material_t * lightMat=yI.createMaterial(areaShapeFn.name().asChar());
						//create geometry
						yI.paramsClearAll();
						int areaID=yI.getNextFreeID();
						yI.startGeometry();
						yI.startTriMesh(areaID,4,2,false,false);
						yI.addVertex(corner.x,corner.y,corner.z);
						yI.addVertex(point1.x,point1.y,point1.z);
						yI.addVertex(point2.x,point2.y,point2.z);
						yI.addVertex(point3.x,point3.y,point3.z);
						yI.addTriangle(0,1,2,lightMat);
						yI.addTriangle(0,2,3,lightMat);
						yI.endTriMesh();
						yI.endGeometry();
						yI.paramsSetInt("object",areaID);

					}

					yI.paramsClearAll();
					yI.paramsSetString("type","arealight");

					cout<<"===============area light=============="<<endl;
					yI.paramsSetInt("samples",samples);

					yI.paramsSetPoint("corner",corner.x, corner.y, corner.z);
					yI.paramsSetPoint("point1",point1.x, point1.y, point1.z);
					yI.paramsSetPoint("point2",point3.x, point3.y, point3.z);

					yI.paramsSetPoint("from",areaP.x, areaP.y, areaP.z);

					yI.paramsSetColor("color",areaR,areaG,areaB);
					yI.paramsSetFloat("power",power);

					cout<<areaShapeFn.name().asChar()<<endl;
					yI.createLight(areaShapeFn.name().asChar());

				}
			}
	}
	//if there is no light in the scene, create a default one
	//but this one will not be available if users create new ones
	if (hasYafLight==false)
	{
		yI.paramsClearAll();
		yI.paramsSetString("type","directional");
		//use camera direction and position so that default light always can be seen no matter where user watch from 
		//M3dView currentView=M3dView::active3dView();
		//MDagPath cameraPath;
		//MFnCamera currentCam(cameraPath);
		//MVector lightPosition=currentCam.eyePoint(MSpace::kWorld);
		//MVector lightDirection=currentCam.viewDirection(MSpace::kWorld);

		//currentView.getCamera(cameraPath);
		yI.paramsSetPoint("direction",0.0,0.0,1.0);
		yI.paramsSetPoint("from",0.0,0.0,0.0);
		yI.paramsSetColor("color",0.8f,0.8f,0.8f);
		yI.paramsSetFloat("power",1.0f);
		yI.paramsSetBool("infinite",true);
		yI.paramsSetFloat("radius",1.0f);
		yI.createLight("yafDefaultLight1");

		yI.paramsClearAll();
		yI.paramsSetString("type","directional");
		yI.paramsSetPoint("direction",1.0,0.0,-1.0);
		yI.paramsSetPoint("from",0.0,0.0,0.0);
		yI.paramsSetColor("color",0.8f,0.8f,0.8f);
		yI.paramsSetFloat("power",1.0f);
		yI.paramsSetBool("infinite",true);
		yI.paramsSetFloat("radius",1.0f);
		yI.createLight("yafDefaultLight2");

		MGlobal::displayWarning("(yafaray) you haven't created your own light yet!");
	}

	return stat;
}
예제 #12
0
//
// Selects objects within the user defined area, then process them
// 
MStatus meshReorderTool::doRelease( MEvent & event )
{
	char buf[1024];

	// Perform the base actions
	MStatus stat = MPxSelectionContext::doRelease(event);

	// Get the list of selected items 
	MGlobal::getActiveSelectionList( fSelectionList );

	//
	//  If there's nothing selected, don't worry about it, just return
	//
	if( fSelectionList.length() != 1 )
	{
		MGlobal::displayWarning( "Components must be selected one at a time" );
		return MS::kSuccess;
	}

	//
	//  Get the selection's details, we must have exactly one component selected
	//
	MObject component;
	MDagPath path;

	MItSelectionList selectionIt (fSelectionList, MFn::kComponent);

	MStringArray	selections;
	selectionIt.getStrings( selections );
	
	if( selections.length() != 1 )
	{
		MGlobal::displayError( "Must select exactly one vertex" );
		return MS::kSuccess;
	}

	if (selectionIt.isDone ())
	{
		MGlobal::displayError( "Selected item not a vertex" );
		return MS::kSuccess;
	}

	if( selectionIt.getDagPath (path, component) != MStatus::kSuccess )
	{
		MGlobal::displayError( "Must select a mesh or its vertex");
		return MS::kSuccess;
	}

	if (!path.node().hasFn(MFn::kMesh) && !(path.node().hasFn(MFn::kTransform) && path.hasFn(MFn::kMesh)))
	{
		MGlobal::displayError( "Must select a mesh or its transform" );
		return MS::kSuccess;
	}

	MFnMesh	meshFn(path);
	MPlug	historyPlug = meshFn.findPlug("inMesh", true);
	if (historyPlug.isDestination())
	{
		MGlobal::displayError( "Mesh has history. Its geometry cannot be modified" );
		return MS::kSuccess;
	}

	MItMeshVertex fIt ( path, component, &stat );
	if( stat != MStatus::kSuccess )
	{
		MGlobal::displayError( "MItMeshVertex failed");
		return MStatus::kFailure;
	}

	if (fIt.count() != 1 )
	{
		sprintf(buf, " Invalid selection '%s'. Vertices must be picked one at a time.", selections[0].asChar() );
		MGlobal::displayError( buf );
		return MS::kSuccess;
	}
	else
	{
		sprintf(buf, "Accepting vertex '%s'", selections[0].asChar() );
		MGlobal::displayInfo(  buf );
	}

	//
	// Now that we know it's valid, process the selection
	//

	fSelectedPathSrc.append( path );
	fSelectedComponentSrc.append( component );

	//
	//  When each of the mesh defined, process it. An error/invalid selection will restart the selection for
	//  that particular mesh.
	//  
	if( fNumSelectedPoints == 2 )
	{
		if( ( stat = meshMapUtils::validateFaceSelection( fSelectedPathSrc, fSelectedComponentSrc, &fSelectedFaceSrc, &fSelectVtxSrc ) ) != MStatus::kSuccess )
		{
			MGlobal::displayError("Must select vertices from the same face of a mesh");
			reset();
			return stat;
		}


		char cmdString[200];
		sprintf(cmdString, "meshReorder %s.vtx[%d] %s.vtx[%d] %s.vtx[%d]", 
		                    fSelectedPathSrc[0].partialPathName().asChar(), fSelectVtxSrc[0],
		                    fSelectedPathSrc[1].partialPathName().asChar(), fSelectVtxSrc[1],
		                    fSelectedPathSrc[2].partialPathName().asChar(), fSelectVtxSrc[2]);

		stat = MGlobal::executeCommand(cmdString, true, true);
		if (stat)
		{
			MGlobal::displayInfo( "Mesh reordering complete" );
		}

		//
		// Empty the selection list since the reodering may move the user's current selection on screen
		//
		MSelectionList empty;
		MGlobal::setActiveSelectionList( empty );

		// 
		// Start again, get new meshes
		//
		reset();	
	}
	else
	{
		//
		// We don't have all the details yet, just move to the next item
		//
		fNumSelectedPoints++;	
	}

	helpStateHasChanged( event );

	return stat;
}
예제 #13
0
liqRibCurvesData::liqRibCurvesData( MObject curveGroup )
: nverts(),
  CVs(),
  NuCurveWidth()
{
	CM_TRACE_FUNC("liqRibCurvesData::liqRibCurvesData("<<curveGroup.apiTypeStr()<<")");

	LIQDEBUGPRINTF( "-> creating nurbs curve group\n" );

	MStatus status( MS::kSuccess );
	MFnDagNode fnDag( curveGroup, &status );
	MFnDagNode fnTrans( fnDag.parent( 0 ) );

	MSelectionList groupList; 
	groupList.add( fnTrans.partialPathName() );
	MDagPath groupPath;
	groupList.getDagPath( 0, groupPath );
	MMatrix m( groupPath.inclusiveMatrix() );

	MStringArray curveList;
	MObjectArray curveObj;
	MDagPathArray curveDag;

	// using the transforms not the nurbsCurves so instances are supported
	MGlobal::executeCommand( MString( "ls -dag -type transform " ) + fnTrans.partialPathName(), curveList );
	for( unsigned i( 0 ); i < curveList.length(); i++ )
	{
		MSelectionList list; 
		list.add( curveList[i] );
		MObject curveNode;
		MDagPath path;
		list.getDependNode( 0, curveNode );
		list.getDagPath( 0, path );
		MFnDagNode fnCurve( curveNode );
		MObject shape( fnCurve.child( 0 ) );
		if( shape.hasFn( MFn::kNurbsCurve ) )
		{
			curveObj.append( curveNode );
			curveDag.append( path );
		}
	}

	if( liqglo.liqglo_renderAllCurves )
	  ncurves = curveObj.length();
	else
		ncurves = 0;  
	  
	if( !ncurves )
		return;

	nverts = shared_array< RtInt >( new RtInt[ ncurves ] );

	unsigned cvcount( 0 );

	unsigned long curvePts(0);
	for( unsigned i( 0 ); i < ncurves; i++ )
	{
		MFnDagNode fnDag( curveObj[i] );
		MFnNurbsCurve fnCurve( fnDag.child( 0 ) );
		nverts[i] = fnCurve.numCVs() + 4;
		cvcount += nverts[i];
	}

	CVs = shared_array< RtFloat >( new RtFloat[ cvcount * 3 ] );

	unsigned k( 0 );
	for( unsigned i( 0 ); i < ncurves; i++ )
	{
		MFnDagNode fnCurve( curveObj[i] );
		MMatrix mCurve( curveDag[i].inclusiveMatrix() );
		mCurve -= m;
		mCurve += MMatrix::identity;

		MObject oCurveChild( fnCurve.child( 0 ) );
		MItCurveCV curveIt( oCurveChild );
		MPoint pt = curveIt.position();
		pt *= mCurve;
		CVs[k++] = (float)pt.x;
		CVs[k++] = (float)pt.y;
		CVs[k++] = (float)pt.z;
		CVs[k++] = (float)pt.x;
		CVs[k++] = (float)pt.y;
		CVs[k++] = (float)pt.z;
		for( curveIt.reset(); !curveIt.isDone(); curveIt.next() )
		{
			pt = curveIt.position();
			pt *= mCurve;
			CVs[k++] = (float)pt.x;
			CVs[k++] = (float)pt.y;
			CVs[k++] = (float)pt.z;
		}
		CVs[k++] = (float)pt.x;
		CVs[k++] = (float)pt.y;
		CVs[k++] = (float)pt.z;
		CVs[k++] = (float)pt.x;
		CVs[k++] = (float)pt.y;
		CVs[k++] = (float)pt.z;
	}

	liqTokenPointer pointsPointerPair;
	pointsPointerPair.set( "P", rPoint, cvcount );
	pointsPointerPair.setDetailType( rVertex );
	pointsPointerPair.setTokenFloats( CVs );

	// Warning: CVs shares ownership with of its data with pointsPointerPair now!
  // Saves us from redundant copying as long as we know what we are doing
	tokenPointerArray.push_back( pointsPointerPair );

	// constant width or not
	float baseWidth( .1 ), tipWidth( .1 );
	bool constantWidth( false );
  liquidGetPlugValue( fnDag, "liquidCurveBaseWidth", baseWidth, status );
  liquidGetPlugValue( fnDag, "liquidCurveTipWidth", tipWidth, status );

	if( tipWidth == baseWidth )
		constantWidth = true;

	if ( constantWidth )
	{
		liqTokenPointer pConstWidthPointerPair;
		pConstWidthPointerPair.set( "constantwidth", rFloat );
		pConstWidthPointerPair.setDetailType( rConstant );
		pConstWidthPointerPair.setTokenFloat( 0, baseWidth );
		tokenPointerArray.push_back( pConstWidthPointerPair );
	}
	else
	{
		NuCurveWidth = shared_array< RtFloat >( new RtFloat[ cvcount - ncurves * 2 ] );
		k = 0;
		for( unsigned i( 0 ); i < ncurves; i++ )
		{
			// easy way just linear - might have to be refined
			MItCurveCV itCurve( curveObj[i] );
			NuCurveWidth[k++] = baseWidth;
			NuCurveWidth[k++] = baseWidth;
			for( unsigned n( 3 ); n < nverts[i] - 3; n++ )
			{
				float difference = tipWidth - baseWidth;
				if( difference < 0 )
					difference *= -1;
				float basew ( baseWidth );
				if( baseWidth > tipWidth )
					NuCurveWidth[k++] = basew - ( n - 2 ) * difference / ( nverts[i] - 5 );
				else
					NuCurveWidth[k++] = basew + ( n - 2 ) * difference / ( nverts[i] - 5 );
			}
			NuCurveWidth[k++] = tipWidth;
			NuCurveWidth[k++] = tipWidth;
		}
		liqTokenPointer widthPointerPair;
		widthPointerPair.set( "width", rFloat, cvcount - ncurves * 2 );
		widthPointerPair.setDetailType( rVarying );
		widthPointerPair.setTokenFloats( NuCurveWidth );
		tokenPointerArray.push_back( widthPointerPair );
	}
	addAdditionalSurfaceParameters( curveGroup );
}
/*
	Utility method to update shader parameters based on available
	lighting information.
*/
static void updateLightShader( MHWRender::MShaderInstance *shaderInstance,
						const MHWRender::MDrawContext & context,
						const MSelectionList * lightList )
{
	if (!shaderInstance)
		return;

	// Check pass context information to see if we are in a shadow 
	// map update pass. If so do nothing.
	//
	const MHWRender::MPassContext & passCtx = context.getPassContext();
	const MStringArray & passSem = passCtx.passSemantics();
	bool handlePass = true;
	for (unsigned int i=0; i<passSem.length() && handlePass; i++)
	{
		// Handle special pass drawing.
		//
		if (passSem[i] == MHWRender::MPassContext::kShadowPassSemantic)
		{
			handlePass = false;
		}
	}
	if (!handlePass) return;

	//
	// Perform light shader update with lighting information
	// If the light list is not empty then use that light's information.
	// Otherwise choose the first appropriate light which can cast shadows.
	//

	// Defaults in case there are no lights
	//
	bool globalShadowsOn = false;
	bool localShadowsOn = false;
	bool shadowDirty = false;
	MFloatVector direction(0.0f, 0.0f, 1.0f);
	float lightIntensity = 0.0f; // If no lights then black out the light
	float lightColor[3] = { 0.0f, 0.0f, 0.0f };

	MStatus status;

	// Scan to find the first N lights that has a direction component in it
	// It's possible we find no lights.
	//
	MHWRender::MDrawContext::LightFilter considerAllSceneLights = MHWRender::MDrawContext::kFilteredIgnoreLightLimit;
	unsigned int lightCount = context.numberOfActiveLights(considerAllSceneLights);
	if (lightCount)
	{
		MFloatArray floatVals;
		MIntArray intVals;
		MHWRender::MTextureAssignment shadowResource;
		shadowResource.texture = NULL;
		MHWRender::MSamplerStateDesc samplerDesc;
		MMatrix shadowViewProj;
		float shadowColor[3] = { 0.0f, 0.0f, 0.0f };

		unsigned int i=0;
		bool foundDirectional = false;
		for (i=0; i<lightCount && !foundDirectional ; i++)
		{
			MHWRender::MLightParameterInformation *lightParam = context.getLightParameterInformation( i, considerAllSceneLights );
			if (lightParam)
			{
				// Prune against light list if any.
				if (lightList && lightList->length())
				{
					if (!lightList->hasItem(lightParam->lightPath()))
						continue;
				}

				MStringArray params;
				lightParam->parameterList(params);
				for (unsigned int p=0; p<params.length(); p++)
				{
					MString pname = params[p];

					MHWRender::MLightParameterInformation::StockParameterSemantic semantic = lightParam->parameterSemantic( pname );
					switch (semantic)
					{
						// Pick a few light parameters to pick up as an example
					case MHWRender::MLightParameterInformation::kWorldDirection:
						lightParam->getParameter( pname, floatVals );
						direction = MFloatVector( floatVals[0], floatVals[1], floatVals[2] );
						foundDirectional = true;
						break;
					case MHWRender::MLightParameterInformation::kIntensity:
						lightParam->getParameter( pname, floatVals );
						lightIntensity = floatVals[0];
						break;
					case MHWRender::MLightParameterInformation::kColor:
						lightParam->getParameter( pname, floatVals );
						lightColor[0] = floatVals[0];
						lightColor[1] = floatVals[1];
						lightColor[2] = floatVals[2];
						break;

						// Pick up shadowing parameters
					case MHWRender::MLightParameterInformation::kGlobalShadowOn:
						lightParam->getParameter( pname, intVals );
						if (intVals.length())
							globalShadowsOn = (intVals[0] != 0) ? true : false;
						break;
					case MHWRender::MLightParameterInformation::kShadowOn:
						lightParam->getParameter( pname, intVals );
						if (intVals.length())
							localShadowsOn = (intVals[0] != 0) ? true : false;
						break;
					case MHWRender::MLightParameterInformation::kShadowViewProj:
						lightParam->getParameter( pname, shadowViewProj);
						break;
					case MHWRender::MLightParameterInformation::kShadowMap:
						lightParam->getParameter( pname, shadowResource );
						break;
					case MHWRender::MLightParameterInformation::kShadowDirty:
						if (intVals.length())
							shadowDirty = (intVals[0] != 0) ? true : false;
						break;
					case MHWRender::MLightParameterInformation::kShadowSamp:
						lightParam->getParameter( pname, samplerDesc );
						break;
					case MHWRender::MLightParameterInformation::kShadowColor:
						lightParam->getParameter( pname, floatVals );
						shadowColor[0] = floatVals[0];
						shadowColor[1] = floatVals[1];
						shadowColor[2] = floatVals[2];
						break;
					default:
						break;
					}
				} /* for params */
			}

			if (foundDirectional && globalShadowsOn && localShadowsOn && shadowResource.texture)
			{
				void *resourceHandle = shadowResource.texture->resourceHandle();
				if (resourceHandle)
				{
					static bool debugShadowBindings = false;
					status  = shaderInstance->setParameter("mayaShadowPCF1_shadowMap", shadowResource );
					if (status == MStatus::kSuccess && debugShadowBindings)
						fprintf(stderr, "Bound shadow map to shader param mayaShadowPCF1_shadowMap\n");
					status  = shaderInstance->setParameter("mayaShadowPCF1_shadowViewProj", shadowViewProj );
					if (status == MStatus::kSuccess && debugShadowBindings)
						fprintf(stderr, "Bound shadow map transform to shader param mayaShadowPCF1_shadowViewProj\n");
					status  = shaderInstance->setParameter("mayaShadowPCF1_shadowColor", &shadowColor[0] );
					if (status == MStatus::kSuccess && debugShadowBindings)
						fprintf(stderr, "Bound shadow map color to shader param mayaShadowPCF1_shadowColor\n");
				}

				MHWRender::MRenderer* renderer = MHWRender::MRenderer::theRenderer();
				if (renderer)
				{
					MHWRender::MTextureManager* textureManager = renderer->getTextureManager();
					if (textureManager)
					{
						textureManager->releaseTexture(shadowResource.texture);
					}
				}
				shadowResource.texture = NULL;
			}
		}
	}

	// Set up parameters which should be set regardless of light existence.
	status = shaderInstance->setParameter("mayaDirectionalLight_direction", &( direction[0] ));
	status = shaderInstance->setParameter("mayaDirectionalLight_intensity", lightIntensity );
	status = shaderInstance->setParameter("mayaDirectionalLight_color", &( lightColor[0] ));
	status = shaderInstance->setParameter("mayaShadowPCF1_mayaGlobalShadowOn", globalShadowsOn);
	status = shaderInstance->setParameter("mayaShadowPCF1_mayaShadowOn", localShadowsOn);
}
예제 #15
0
//The writer simply goes gathers all objects from the scene.
//We will check if the object has a transform, if so, we will check
//if it's either a nurbsSphere, nurbsCone or nurbsCylinder.  If so,
//we will write it out.
MStatus LepTranslator::writer ( const MFileObject& file,
                                const MString& options,
                                MPxFileTranslator::FileAccessMode mode)
{
    MStatus status;
	bool showPositions = false;
    unsigned int  i;
    const MString fname = file.fullName();

    ofstream newf(fname.asChar(), ios::out);
    if (!newf) {
        // open failed
        cerr << fname << ": could not be opened for reading\n";
        return MS::kFailure;
    }
    newf.setf(ios::unitbuf);

    if (options.length() > 0) {
        // Start parsing.
        MStringArray optionList;
        MStringArray theOption;
        options.split(';', optionList);    // break out all the options.
        
        for( i = 0; i < optionList.length(); ++i ){
            theOption.clear();
            optionList[i].split( '=', theOption );
            if( theOption[0] == MString("showPositions") &&
                                                    theOption.length() > 1 ) {
                if( theOption[1].asInt() > 0 ){
                    showPositions = true;
                }else{
                    showPositions = false;
                }
            }
        }
    }

    // output our magic number
    newf << "<LEP>\n";

    MItDag dagIterator( MItDag::kBreadthFirst, MFn::kInvalid, &status);

    if ( !status) {
        status.perror ("Failure in DAG iterator setup");
        return MS::kFailure;
    }

    MSelectionList selection;
    MGlobal::getActiveSelectionList (selection);
    MItSelectionList selIterator (selection, MFn::kDagNode);

    bool done = false;
    while (true) 
    {
        MObject currentNode;
        switch (mode)
        {
            case MPxFileTranslator::kSaveAccessMode:
            case MPxFileTranslator::kExportAccessMode:
                if (dagIterator.isDone ())
                    done = true;
                else {
                    currentNode = dagIterator.item ();
                    dagIterator.next ();
                }
                break;
            case MPxFileTranslator::kExportActiveAccessMode:
                if (selIterator.isDone ())
                    done = true;
                else {
                    selIterator.getDependNode (currentNode);
                    selIterator.next ();
                }
                break;
            default:
                cerr << "Unrecognized write mode: " << mode << endl;
                break;
        }
        if (done)
            break;

        //We only care about nodes that are transforms
        MFnTransform dagNode(currentNode, &status);
        if ( status == MS::kSuccess ) 
        {
            MString nodeNameNoNamespace=MNamespace::stripNamespaceFromName(dagNode.name());
            for (i = 0; i < numPrimitives; ++i) {                
                if(nodeNameNoNamespace.indexW(primitiveStrings[i]) >= 0){
                    // This is a node we support
                    newf << primitiveCommands[i] << " -n " << nodeNameNoNamespace << endl;
                    if (showPositions) {
                        MVector pos;
                        pos = dagNode.getTranslation(MSpace::kObject);
                        newf << "move " << pos.x << " " << pos.y << " " << pos.z << endl;
                    }
                }
            }
        }//if (status == MS::kSuccess)
    }//while loop

    newf.close();
    return MS::kSuccess;
}
예제 #16
0
void NifMeshExporterSkyrim::ExportMesh( MObject dagNode ) {
	//out << "NifTranslator::ExportMesh {";
	ComplexShape cs;
	MStatus stat;
	MObject mesh;

	//Find Mesh child of given transform object
	MFnDagNode nodeFn(dagNode);

	cs.SetName(this->translatorUtils->MakeNifName(nodeFn.name()));


	for (int i = 0; i != nodeFn.childCount(); ++i) {
		// get a handle to the child
		if (nodeFn.child(i).hasFn(MFn::kMesh)) {
			MFnMesh tempFn(nodeFn.child(i));
			//No history items
			if (!tempFn.isIntermediateObject()) {
				//out << "Found a mesh child." << endl;
				mesh = nodeFn.child(i);
				break;
			}
		}
	}

	MFnMesh visibleMeshFn(mesh, &stat);
	if (stat != MS::kSuccess) {
		//out << stat.errorString().asChar() << endl;
		throw runtime_error("Failed to create visibleMeshFn.");
	}

	//out << visibleMeshFn.name().asChar() << ") {" << endl;
	MFnMesh meshFn;
	MObject dataObj;
	MPlugArray inMeshPlugArray;
	MPlug childPlug;
	MPlug geomPlug;
	MPlug inputPlug;

	// this will hold the returned vertex positions
	MPointArray vts;

	//For now always use the visible mesh
	meshFn.setObject(mesh);

	//out << "Use the function set to get the points" << endl;
	// use the function set to get the points
	stat = meshFn.getPoints(vts);
	if (stat != MS::kSuccess) {
		//out << stat.errorString().asChar() << endl;
		throw runtime_error("Failed to get points.");
	}

	//Maya won't store any information about objects with no vertices.  Just skip it.
	if (vts.length() == 0) {
		MGlobal::displayWarning("An object in this scene has no vertices.  Nothing will be exported.");
		return;
	}

	vector<WeightedVertex> nif_vts(vts.length());
	for (int i = 0; i != vts.length(); ++i) {
		nif_vts[i].position.x = float(vts[i].x);
		nif_vts[i].position.y = float(vts[i].y);
		nif_vts[i].position.z = float(vts[i].z);
	}

	//Set vertex info later since it includes skin weights
	//cs.SetVertices( nif_vts );

	//out << "Use the function set to get the colors" << endl;
	MColorArray myColors;
	meshFn.getFaceVertexColors(myColors);

	//out << "Prepare NIF color vector" << endl;
	vector<Color4> niColors(myColors.length());
	for (unsigned int i = 0; i < myColors.length(); ++i) {
		niColors[i] = Color4(myColors[i].r, myColors[i].g, myColors[i].b, myColors[i].a);
	}
	cs.SetColors(niColors);


	// this will hold the returned vertex positions
	MFloatVectorArray nmls;

	//out << "Use the function set to get the normals" << endl;
	// use the function set to get the normals
	stat = meshFn.getNormals(nmls, MSpace::kTransform);
	if (stat != MS::kSuccess) {
		//out << stat.errorString().asChar() << endl;
		throw runtime_error("Failed to get normals");
	}

	//out << "Prepare NIF normal vector" << endl;
	vector<Vector3> nif_nmls(nmls.length());
	for (int i = 0; i != nmls.length(); ++i) {
		nif_nmls[i].x = float(nmls[i].x);
		nif_nmls[i].y = float(nmls[i].y);
		nif_nmls[i].z = float(nmls[i].z);
	}
	cs.SetNormals(nif_nmls);

	//out << "Use the function set to get the UV set names" << endl;
	MStringArray uvSetNames;
	MString baseUVSet;
	MFloatArray myUCoords;
	MFloatArray myVCoords;
	bool has_uvs = false;

	// get the names of the uv sets on the mesh
	meshFn.getUVSetNames(uvSetNames);

	vector<TexCoordSet> nif_uvs;

	//Record assotiation between name and uv set index for later
	map<string, int> uvSetNums;

	int set_num = 0;
	for (unsigned int i = 0; i < uvSetNames.length(); ++i) {
		if (meshFn.numUVs(uvSetNames[i]) > 0) {
			TexType tt;
			string set_name = uvSetNames[i].asChar();
			if (set_name == "base" || set_name == "map1") {
				tt = BASE_MAP;
			}
			else if (set_name == "dark") {
				tt = DARK_MAP;
			}
			else if (set_name == "detail") {
				tt = DETAIL_MAP;
			}
			else if (set_name == "gloss") {
				tt = GLOSS_MAP;
			}
			else if (set_name == "glow") {
				tt = GLOW_MAP;
			}
			else if (set_name == "bump") {
				tt = BUMP_MAP;
			}
			else if (set_name == "decal0") {
				tt = DECAL_0_MAP;
			}
			else if (set_name == "decal1") {
				tt = DECAL_1_MAP;
			}
			else {
				tt = BASE_MAP;
			}

			//Record the assotiation
			uvSetNums[set_name] = set_num;

			//Get the UVs
			meshFn.getUVs(myUCoords, myVCoords, &uvSetNames[i]);

			//Make sure this set actually has some UVs in it.  Maya sometimes returns empty UV sets.
			if (myUCoords.length() == 0) {
				continue;
			}

			//Store the data
			TexCoordSet tcs;
			tcs.texType = tt;
			tcs.texCoords.resize(myUCoords.length());
			for (unsigned int j = 0; j < myUCoords.length(); ++j) {
				tcs.texCoords[j].u = myUCoords[j];
				//Flip the V coords
				tcs.texCoords[j].v = 1.0f - myVCoords[j];
			}
			nif_uvs.push_back(tcs);

			baseUVSet = uvSetNames[i];
			has_uvs = true;

			set_num++;
		}
	}

	cs.SetTexCoordSets(nif_uvs);

	// this will hold references to the shaders used on the meshes
	MObjectArray Shaders;

	// this is used to hold indices to the materials returned in the object array
	MIntArray    FaceIndices;

	//out << "Get the connected shaders" << endl;
	// get the shaders used by the i'th mesh instance
	// Assume this is not instanced for now
	// TODO support instancing properly
	stat = visibleMeshFn.getConnectedShaders(0, Shaders, FaceIndices);

	if (stat != MS::kSuccess) {
		//out << stat.errorString().asChar() << endl;
		throw runtime_error("Failed to get connected shader list.");

	}

	vector<ComplexFace> nif_faces;


	//Add shaders to propGroup array
	vector< vector<NiPropertyRef> > propGroups;
	for (unsigned int shader_num = 0; shader_num < Shaders.length(); ++shader_num) {

		//Maya sometimes lists shaders that are not actually attached to any face.  Disregard them.
		bool shader_is_used = false;
		for (size_t f = 0; f < FaceIndices.length(); ++f) {
			if (FaceIndices[f] == shader_num) {
				shader_is_used = true;
				break;
			}
		}

		if (shader_is_used == false) {
			//Shader isn't actually used, so continue to the next one.
			continue;
		}

		//out << "Found attached shader:  ";
		//Attach all properties previously associated with this shader to
		//this NiTriShape
		MFnDependencyNode fnDep(Shaders[shader_num]);

		//Find the shader that this shading group connects to
		MPlug p = fnDep.findPlug("surfaceShader");
		MPlugArray plugs;
		p.connectedTo(plugs, true, false);
		for (unsigned int i = 0; i < plugs.length(); ++i) {
			if (plugs[i].node().hasFn(MFn::kLambert)) {
				fnDep.setObject(plugs[i].node());
				break;
			}
		}

		//out << fnDep.name().asChar() << endl;
		vector<NiPropertyRef> niProps = this->translatorData->shaders[fnDep.name().asChar()];

		propGroups.push_back(niProps);
	}
	cs.SetPropGroups(propGroups);

	//out << "Export vertex and normal data" << endl;
	// attach an iterator to the mesh
	MItMeshPolygon itPoly(mesh, &stat);
	if (stat != MS::kSuccess) {
		throw runtime_error("Failed to create polygon iterator.");
	}

	// Create a list of faces with vertex IDs, and duplicate normals so they have the same ID
	for (; !itPoly.isDone(); itPoly.next()) {
		int poly_vert_count = itPoly.polygonVertexCount(&stat);

		if (stat != MS::kSuccess) {
			throw runtime_error("Failed to get vertex count.");
		}

		//Ignore polygons with less than 3 vertices
		if (poly_vert_count < 3) {
			continue;
		}

		ComplexFace cf;

		//Assume all faces use material 0 for now
		cf.propGroupIndex = 0;

		for (int i = 0; i < poly_vert_count; ++i) {
			ComplexPoint cp;

			cp.vertexIndex = itPoly.vertexIndex(i);
			cp.normalIndex = itPoly.normalIndex(i);
			if (niColors.size() > 0) {
				int color_index;
				stat = meshFn.getFaceVertexColorIndex(itPoly.index(), i, color_index);
				if (stat != MS::kSuccess) {
					//out << stat.errorString().asChar() << endl;
					throw runtime_error("Failed to get vertex color.");
				}
				cp.colorIndex = color_index;
			}

			//Get the UV set names used by this particular vertex
			MStringArray vertUvSetNames;
			itPoly.getUVSetNames(vertUvSetNames);
			for (unsigned int j = 0; j < vertUvSetNames.length(); ++j) {
				TexCoordIndex tci;
				tci.texCoordSetIndex = uvSetNums[vertUvSetNames[j].asChar()];
				int uv_index;
				itPoly.getUVIndex(i, uv_index, &vertUvSetNames[j]);
				tci.texCoordIndex = uv_index;
				cp.texCoordIndices.push_back(tci);
			}
			cf.points.push_back(cp);
		}
		nif_faces.push_back(cf);
	}

	//Set shader/face association
	if (nif_faces.size() != FaceIndices.length()) {
		throw runtime_error("Num faces found do not match num faces reported.");
	}
	for (unsigned int face_index = 0; face_index < nif_faces.size(); ++face_index) {
		nif_faces[face_index].propGroupIndex = FaceIndices[face_index];
	}

	cs.SetFaces(nif_faces);

	//--Skin Processing--//

	//Look up any skin clusters
	if (this->translatorData->meshClusters.find(visibleMeshFn.fullPathName().asChar()) != this->translatorData->meshClusters.end()) {
		const vector<MObject> & clusters = this->translatorData->meshClusters[visibleMeshFn.fullPathName().asChar()];
		if (clusters.size() > 1) {
			throw runtime_error("Objects with multiple skin clusters affecting them are not currently supported.  Try deleting the history and re-binding them.");
		}

		vector<MObject>::const_iterator cluster = clusters.begin();
		if (cluster->isNull() != true) {
			MFnSkinCluster clusterFn(*cluster);


			//out << "Processing skin..." << endl;
			//Get path to visible mesh
			MDagPath meshPath;
			visibleMeshFn.getPath(meshPath);

			//out << "Getting a list of all verticies in this mesh" << endl;
			//Get a list of all vertices in this mesh
			MFnSingleIndexedComponent compFn;
			MObject vertices = compFn.create(MFn::kMeshVertComponent);
			MItGeometry gIt(meshPath);
			MIntArray vertex_indices(gIt.count());
			for (int vert_index = 0; vert_index < gIt.count(); ++vert_index) {
				vertex_indices[vert_index] = vert_index;
			}
			compFn.addElements(vertex_indices);

			//out << "Getting Influences" << endl;
			//Get influences
			MDagPathArray myBones;
			clusterFn.influenceObjects(myBones, &stat);

			//out << "Creating a list of NiNodeRefs of influences." << endl;
			//Create list of NiNodeRefs of influences
			vector<NiNodeRef> niBones(myBones.length());
			for (unsigned int bone_index = 0; bone_index < niBones.size(); ++bone_index) {
				const char* boneName = myBones[bone_index].fullPathName().asChar();
				if (this->translatorData->nodes.find(myBones[bone_index].fullPathName().asChar()) == this->translatorData->nodes.end()) {
					//There is a problem; one of the joints was not exported.  Abort.
					throw runtime_error("One of the joints necessary to export a bound skin was not exported.");
				}
				niBones[bone_index] = this->translatorData->nodes[myBones[bone_index].fullPathName().asChar()];
			}

			//out << "Getting weights from Maya" << endl;
			//Get weights from Maya
			MDoubleArray myWeights;
			unsigned int bone_count = myBones.length();
			stat = clusterFn.getWeights(meshPath, vertices, myWeights, bone_count);
			if (stat != MS::kSuccess) {
				//out << stat.errorString().asChar() << endl;
				throw runtime_error("Failed to get vertex weights.");
			}

			//out << "Setting skin influence list in ComplexShape" << endl;
			//Set skin information in ComplexShape
			cs.SetSkinInfluences(niBones);

			//out << "Adding weights to ComplexShape vertices" << endl;
			//out << "Number of weights:  " << myWeights.length() << endl;
			//out << "Number of bones:  " << myBones.length() << endl;
			//out << "Number of Maya vertices:  " << gIt.count() << endl;
			//out << "Number of NIF vertices:  " << int(nif_vts.size()) << endl;
			unsigned int weight_index = 0;
			SkinInfluence sk;
			for (unsigned int vert_index = 0; vert_index < nif_vts.size(); ++vert_index) {
				for (unsigned int bone_index = 0; bone_index < myBones.length(); ++bone_index) {
					//out << "vert_index:  " << vert_index << "  bone_index:  " << bone_index << "  weight_index:  " << weight_index << endl;	
					// Only bother with weights that are significant
					if (myWeights[weight_index] > 0.0f) {
						sk.influenceIndex = bone_index;
						sk.weight = float(myWeights[weight_index]);

						nif_vts[vert_index].weights.push_back(sk);
					}
					++weight_index;
				}
			}
		}

		MPlugArray connected_dismember_plugs;
		MObjectArray dismember_nodes;
		meshFn.findPlug("message").connectedTo(connected_dismember_plugs, false, true);

		bool has_valid_dismemember_partitions = true;
		int faces_count = cs.GetFaces().size();
		int current_face_index;
		vector<BodyPartList> body_parts_list;
		vector<uint> dismember_faces(faces_count, 0);

		for (int x = 0; x < connected_dismember_plugs.length(); x++) {
			MFnDependencyNode dependency_node(connected_dismember_plugs[x].node());
			if (dependency_node.typeName() == "nifDismemberPartition") {
				dismember_nodes.append(dependency_node.object());
			}
		}

		if (dismember_nodes.length() == 0) {
			has_valid_dismemember_partitions = false;
		}
		else {
			int blind_data_id;
			int blind_data_value;
			MStatus status;
			MPlug target_faces_plug;
			MItMeshPolygon it_polygons(meshFn.object());
			MString mel_command;
			MStringArray current_body_parts_flags;
			MFnDependencyNode current_dismember_node;
			MFnDependencyNode current_blind_data_node;

			//Naive sort here, there is no reason and is extremely undesirable and not recommended to have more
			//than 10-20 dismember partitions out of many reasons, so it's okay here
			//as it makes the code easier to understand
			vector<int> dismember_nodes_id(dismember_nodes.length(), -1);
			for (int x = 0; x < dismember_nodes.length(); x++) {
				current_dismember_node.setObject(dismember_nodes[x]);
				connected_dismember_plugs.clear();
				current_dismember_node.findPlug("targetFaces").connectedTo(connected_dismember_plugs, true, false);
				if (connected_dismember_plugs.length() == 0) {
					has_valid_dismemember_partitions = false;
					break;
				}
				current_blind_data_node.setObject(connected_dismember_plugs[0].node());
				dismember_nodes_id[x] = current_blind_data_node.findPlug("typeId").asInt();
			}
			for (int x = 0; x < dismember_nodes.length() - 1; x++) {
				for (int y = x + 1; y < dismember_nodes.length(); y++) {
					if (dismember_nodes_id[x] > dismember_nodes_id[y]) {
						MObject aux = dismember_nodes[x];
						blind_data_id = dismember_nodes_id[x];
						dismember_nodes[x] = dismember_nodes[y];
						dismember_nodes_id[x] = dismember_nodes_id[y];
						dismember_nodes[y] = aux;
						dismember_nodes_id[y] = blind_data_id;
					}
				}
			}

			for (int x = 0; x < dismember_nodes.length(); x++) {
				current_dismember_node.setObject(dismember_nodes[x]);
				target_faces_plug = current_dismember_node.findPlug("targetFaces");
				connected_dismember_plugs.clear();
				target_faces_plug.connectedTo(connected_dismember_plugs, true, false);
				if (connected_dismember_plugs.length() > 0) {
					current_blind_data_node.setObject(connected_dismember_plugs[0].node());
					current_face_index = 0;
					blind_data_id = current_blind_data_node.findPlug("typeId").asInt();
					for (it_polygons.reset(); !it_polygons.isDone(); it_polygons.next()) {
						if (it_polygons.polygonVertexCount() >= 3) {
							status = meshFn.getIntBlindData(it_polygons.index(), MFn::Type::kMeshPolygonComponent, blind_data_id, "dismemberValue", blind_data_value);
							if (status == MStatus::kSuccess && blind_data_value == 1 &&
								meshFn.hasBlindDataComponentId(it_polygons.index(), MFn::Type::kMeshPolygonComponent, blind_data_id)) {
								dismember_faces[current_face_index] = x;
							}
							current_face_index++;
						}
					}
				}
				else {
					has_valid_dismemember_partitions = false;
					break;
				}

				mel_command = "getAttr ";
				mel_command += current_dismember_node.name();
				mel_command += ".bodyPartsFlags";
				status = MGlobal::executeCommand(mel_command, current_body_parts_flags);
				BSDismemberBodyPartType body_part_type = NifDismemberPartition::stringArrayToBodyPartType(current_body_parts_flags);
				current_body_parts_flags.clear();

				mel_command = "getAttr ";
				mel_command += current_dismember_node.name();
				mel_command += ".partsFlags";
				status = MGlobal::executeCommand(mel_command, current_body_parts_flags);
				BSPartFlag part_type = NifDismemberPartition::stringArrayToPart(current_body_parts_flags);
				current_body_parts_flags.clear();

				BodyPartList body_part;
				body_part.bodyPart = body_part_type;
				body_part.partFlag = part_type;
				body_parts_list.push_back(body_part);
			}
		}

		if (has_valid_dismemember_partitions == false) {
			MGlobal::displayWarning("No proper dismember partitions, generating default ones for " + meshFn.name());

			for (int x = 0; x < dismember_faces.size(); x++) {
				dismember_faces[x] = 0;
			}

			BodyPartList body_part;
			body_part.bodyPart = (BSDismemberBodyPartType)0;
			body_part.partFlag = (BSPartFlag)(PF_EDITOR_VISIBLE | PF_START_NET_BONESET);
			body_parts_list.clear();
			body_parts_list.push_back(body_part);
		}

		cs.SetDismemberPartitionsBodyParts(body_parts_list);
		cs.SetDismemberPartitionsFaces(dismember_faces);
	}

	//out << "Setting vertex info" << endl;
	//Set vertex info now that any skins have been processed
	cs.SetVertices(nif_vts);

	//ComplexShape is now complete, so split it

	//Get parent
	NiNodeRef parNode = this->translatorUtils->GetDAGParent(dagNode);
	Matrix44 transform = Matrix44::IDENTITY;
	vector<NiNodeRef> influences = cs.GetSkinInfluences();
	if (influences.size() > 0) {
		//This is a skin, so we use the common ancestor of all influences
		//as the parent
		vector<NiAVObjectRef> objects;
		for (size_t i = 0; i < influences.size(); ++i) {
			objects.push_back(StaticCast<NiAVObject>(influences[i]));
		}

		//Get world transform of existing parent
		Matrix44 oldParWorld = parNode->GetWorldTransform();

		//Set new parent node
		parNode = FindCommonAncestor(objects);

		transform = oldParWorld * parNode->GetWorldTransform().Inverse();
	}

	//Get transform using temporary NiAVObject
	NiAVObjectRef tempAV = new NiAVObject;
	this->nodeExporter->ExportAV(tempAV, dagNode);

	NiAVObjectRef avObj;
	if (this->translatorOptions->exportTangentSpace == "falloutskyrimtangentspace") {
		//out << "Split ComplexShape from " << meshFn.name().asChar() << endl;
		avObj = cs.Split(parNode, tempAV->GetLocalTransform() * transform, this->translatorOptions->exportBonesPerSkinPartition,
			this->translatorOptions->exportAsTriStrips, true, this->translatorOptions->exportMinimumVertexWeight, 16);
	}
	else {
		avObj = cs.Split(parNode, tempAV->GetLocalTransform() * transform, this->translatorOptions->exportBonesPerSkinPartition,
			this->translatorOptions->exportAsTriStrips, false, this->translatorOptions->exportMinimumVertexWeight);
	}


	//out << "Get the NiAVObject portion of the root of the split" <<endl;
	//Get the NiAVObject portion of the root of the split
	avObj->SetName(tempAV->GetName());
	avObj->SetVisibility(tempAV->GetVisibility());
	avObj->SetFlags(tempAV->GetFlags());

	//If polygon mesh is hidden, hide tri_shape
	MPlug vis = visibleMeshFn.findPlug(MString("visibility"));
	bool visibility;
	vis.getValue(visibility);


	NiNodeRef splitRoot = DynamicCast<NiNode>(avObj);
	if (splitRoot != NULL) {
		//Root is a NiNode with NiTriBasedGeom children.
		vector<NiAVObjectRef> children = splitRoot->GetChildren();
		for (unsigned c = 0; c < children.size(); ++c) {
			//Set the default collision propogation flag to "use triangles"
			children[c]->SetFlags(2);
			// Make the mesh invisible if necessary
			if (visibility == false) {
				children[c]->SetVisibility(false);
			}
		}

	}
	else {
		//Root must be a NiTriBasedGeom.  Make it invisible if necessary
		if (visibility == false) {
			avObj->SetVisibility(false);
		}
	}

}
void ShaderValidConnection::setValidConnection()
{
	MStringArray validConnection;
	
	//null (dummy shader)
	validConnection.clear();
	validConnection.append("");
	validConnectionMap.insert(std::make_pair("null", validConnection));	

	// MATERIAL -----------------------------------
	/// surface ///
	//anisotropic

	//hairTubeShader

	//lambert
	validConnection.clear();
	validConnection.append("color");
	validConnection.append("transparency");
	validConnection.append("ambientColor");
	validConnection.append("incandescence");
	validConnection.append("diffuse");
	validConnection.append("outColor");
	validConnection.append("outTransparency");
	validConnectionMap.insert(std::make_pair("lambert", validConnection));	

	//layered shader

	//blinn
	validConnection.clear();
	validConnection.append("color");
	validConnection.append("transparency");
	validConnection.append("ambientColor");
	validConnection.append("incandescence");
	validConnection.append("diffuse");
	validConnection.append("eccentricity");
	validConnection.append("specularRollOff");
	validConnection.append("specularColor");
	validConnection.append("reflectivity");
	validConnection.append("reflectedColor");
	validConnection.append("outColor");
	validConnectionMap.insert(std::make_pair("blinn", validConnection));	

	//oceanShader 

	//phong
	validConnection.clear();
	validConnection.append("color");
	validConnection.append("transparency");
	validConnection.append("ambientColor");
	validConnection.append("incandescence");
	validConnection.append("normalCamera");
	validConnection.append("diffuse");
	validConnection.append("translucence");
	validConnection.append("translucenceDepth");
	validConnection.append("translucenceFocus");
	validConnection.append("cosinePower");
	validConnection.append("specularColor");
	validConnection.append("reflectivity");
	validConnection.append("reflectedColor");
	validConnection.append("matteOpacityMode");
	validConnection.append("matteOpacity");
	validConnection.append("reflectionLimit");
	validConnection.append("outColor");
	validConnection.append("outTransparency");
	validConnectionMap.insert(std::make_pair("phong", validConnection));	

	//phongE

	//rampShader

	//shadingMap

	//surfaceShader

	//useBackground

	/// Volumetric ///
	//envFog

	//fluidShape

	//lightFog

	//particleCloud

	//volumeFog

	//volumeShader

	/// DISPLACEMENT ///
	//displacement

	/// 2D Texture (normal)///
	//bulge

	//checker
	validConnection.clear();
	validConnection.append("alphaGain");
	validConnection.append("alphaIsLuminance");
	validConnection.append("alphaOffset");
	validConnection.append("color1");//color1
	validConnection.append("color1R");
	validConnection.append("color1G");
	validConnection.append("color1B");
	validConnection.append("color2");//color2
	validConnection.append("color2R");
	validConnection.append("color2G");
	validConnection.append("color2B");
	validConnection.append("colorGain");
	validConnection.append("colorOffset");
	validConnection.append("contrast");
	validConnection.append("defaultColor");
	validConnection.append("filter");
	validConnection.append("filterOffset");
	validConnection.append("invert");
	validConnection.append("uvCoord");//uvCoord
	validConnection.append("uCoord");
	validConnection.append("vCoord");
	validConnection.append("outAlpha");
	validConnection.append("outColor");//outColor
	validConnection.append("outColorR");
	validConnection.append("outColorG");
	validConnection.append("outColorB");
	validConnectionMap.insert(std::make_pair("checker", validConnection));	

	//cloth

	// file
	validConnection.clear();
	validConnection.append("alphaGain");
	validConnection.append("alphaIsLuminance");
	validConnection.append("alphaOffset");
	validConnection.append("colorGain");
	validConnection.append("colorOffset");
	validConnection.append("defaultColor");
	validConnection.append("fileTextureName");
	validConnection.append("filterType");
	validConnection.append("filter");
	validConnection.append("filterOffset");
	validConnection.append("invert");
	validConnection.append("uvCoord");
	validConnection.append("fileHasAlpha");
	validConnection.append("outAlpha");
	validConnection.append("outColor");
	validConnection.append("outTransparency");
	validConnectionMap.insert(std::make_pair("file", validConnection));	

	//fluidTexture2D

	//fractal

	//grid

	//mountain

	//movie

	//noise

	//ocean

	//psdFileTex

	//ramp

	//water

	/// 3D Textures ///
	//brownian

	//cloud

	//crater

	//fluidTexture3D

	//granite

	//leather

	//marble

	//rock

	//snow

	//solidFractal

	//stucco

	//volumeNoise

	//wood

	/// Env Textures ///
	//envBall

	//envChrome

	//envCube

	//envSky 

	//envSphere

	/// other textures ///
	//layeredTexture

	/// Lights ///
	//ambientLight

	//areaLight

	//directionalLight

	//pointLight

	//spotLight

	//volumeLight

	/// General utilities ///
	//arrayMapper

	//bump2d
	validConnection.clear();
	validConnection.append("bumpValue");
	validConnection.append("bumpDepth");
	validConnection.append("bumpInterp");
	validConnection.append("bumpFilter");
	validConnection.append("bumpFilterOffset");
	validConnection.append("normalCamera");
	validConnection.append("bumpNormal");
	validConnection.append("outNormal");
	validConnectionMap.insert(std::make_pair("bump2d", validConnection));

	//bump3d
	validConnection.clear();
	validConnection.append("bumpValue");
	validConnection.append("bumpDepth");
	validConnection.append("bumpFilter");
	validConnection.append("bumpFilterOffset");
	validConnection.append("normalCamera");
	validConnection.append("outNormal");
	validConnectionMap.insert(std::make_pair("bump3d", validConnection));

	//condition

	//distanceBetween

	//heightField

	//lightInfo

	//multiplyDivide

	//place2dTexture
	validConnection.clear();
	validConnection.append("uvCoord");
	validConnection.append("coverageU");
	validConnection.append("coverageV");
	validConnection.append("coverage");
	validConnection.append("mirrorU");
	validConnection.append("mirrorV");
	validConnection.append("noiseU");
	validConnection.append("noiseV");
	validConnection.append("noiseUV");
	validConnection.append("offsetU");
	validConnection.append("offsetV");
	validConnection.append("offset");
	validConnection.append("repeatU");
	validConnection.append("repeatV");
	validConnection.append("repeatUV");
	validConnection.append("rotateFrame");
	validConnection.append("rotateUV");
	validConnection.append("stagger");
	validConnection.append("translateFrameU");
	validConnection.append("translateFrameV");
	validConnection.append("translateFrame");
	validConnection.append("wrapU");
	validConnection.append("wrapV");
	validConnection.append("outUV");
	validConnectionMap.insert(std::make_pair("place2dTexture", validConnection));	

	//place3dTexture

	//plusMinusAverage

	//projection

	//reverse

	//samplerInfo

	//setRange

	//stencil

	//studioClearCoat

	//uvChooser

	//vectorProduct

	/// color utilities ///
	//blendColors

	//clamp

	//contrast

	//gammaCorrect

	//hsvToRgb

	//luminance

	//remapColor

	//remapHsv

	//remapValue

	//rgbToHsv

	//smear

	//surfaceLuminance

	/// switch utilities ///
	//doubleShadingSwitch

	//quadShadingSwitch

	//singleShadingSwitch

	//tripleShadingSwitch

	/// particle utilities ///
	//particleSamplerInfo

	/// image planes ///
	//imagePlane

	/// glow ///
	//opticalFX

	setValidConnection_mi();


}
예제 #18
0
MStatus boingRbCmd::redoIt()
{
    if (argParser->isFlagSet("help") || argParser->isFlagSet("h"))
    {
        MString helpMsg = "boingRB - command : Boing - bullet plugin by Risto Puukko\n";
        helpMsg += "---------------------------------------------------------\n";
        helpMsg += "boingRB [flag] [args] \n";
        helpMsg += "\n";
        helpMsg += "flags :\n";
        helpMsg += "  -getAttr [name.attr]\n";
        helpMsg += "     example : boingRb -getAttr (\"boingRb1.velocity\");\n" ;
        helpMsg += "\n";
        helpMsg += "  -getAttr [*.attr]\n";
        helpMsg += "     example : boingRb -getAttr (\"*.name\");\n" ;
        helpMsg += "\n";
        helpMsg += "  -setAttr [name.attr] -value [float float float ]\n";
        helpMsg += "     example : boingRb -setAttr (\"boingRb1.velocity\") -value 0 4 3 ;\n" ;
        helpMsg += "\n";
        helpMsg += "  -addAttr [name.attr] -type [int/double/string/vector]\n";
        helpMsg += "     example : boingRb -addAttr \"sampleRb.IntAttribute\" -type \"int\";\n" ;
        helpMsg += "     example : boingRb -addAttr \"sampleRb.VectorAttribute\" -type \"vector\";\n" ;
        helpMsg += "\n";
        helpMsg += "  -create [ ( \"name=string;geo=string;velocity/vel=float,float,float;position/pos=float,float,float\" )]\n";
        helpMsg += "     example : boingRb -create (\"name=sampleRb;geo=pCubeShape1;pos=0,4,0\");\n";
        helpMsg += "\n";
        helpMsg += "  -exists [name]\n";
        helpMsg += "     example : boingRb -exists \"sampleRb\";\n" ;
        helpMsg += "\n";
        helpMsg += "  -delete [name]\n";
        helpMsg += "     example : boingRb -delete \"sampleRb\";\n";
        helpMsg += "\n";
        helpMsg += "---------------------------------------------------------\n";

        
        MGlobal::displayInfo(helpMsg);
        return MS::kSuccess;
    }
    
    isSetAttr = argParser->isFlagSet("-setAttr");
    isGetAttr = argParser->isFlagSet("-getAttr");
    isAddAttr = argParser->isFlagSet("-addAttr");
    isType = argParser->isFlagSet("-type");
    isExists = argParser->isFlagSet("-exists");
    isAttributeExist = argParser->isFlagSet("-attributeExist");
    isCreate = argParser->isFlagSet("-create");
    isDelete = argParser->isFlagSet("-delete");
    isValue = argParser->isFlagSet("-value");
    
    //std::cout<<"argsList : "<<*argsList<<std::endl;
    //unsigned i;
    //MStatus stat;
    //MVector res;
    // Parse the arguments.
    /*
    for (i = 0; i <argsList->length (); i++) {
        //MString arg = argsList->asString(i, &stat);
        //if (MS::kSuccess == stat) std::cout<<"arg["<<i<<"] : "<<arg<<std::endl;
        if (
            MString ("-setAttr") == argsList->asString(i, &stat) &&
            MString ("-value") == argsList->asString(i+2, &stat) &&
            MS::kSuccess == stat
            ) {
            for (unsigned j=3; j!=6; ++j)
                res[j-3 ] = argsList->asDouble (j, &stat);
        }
    }
    
    std::cout<<"res : "<<res<<std::endl;
    */
    if (isSetAttr && isValue) {
        
        MString sAttr;
        argParser->getFlagArgument("setAttr", 0, sAttr);
        //std::cout<<sAttr<<std::endl;
        MStringArray jobArgsArray = parseArguments(sAttr, ".");
        MString rbName = jobArgsArray[0];
        MString attr = checkAttribute(jobArgsArray[1]);
        //std::cout<<"attr : "<<attr<<std::endl;
        
        if ( attr == "custom" ) {
            MString customAttr = jobArgsArray[1];
            //char * custAttr = (char*)customAttr.asChar();
            //std::cout<<"customAttr : "<<customAttr<<std::endl;
            shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node();
            bSolverNode::m_custom_data *data = b_solv->getdata(rbName);
            //std::cout<<"data : "<<data<<std::endl;
            if (!data) return MS::kFailure;
            //std::cout<<"data->m_int_data : "<<data->m_int_data<<std::endl;
            MString type = b_solv->getAttrType(data, customAttr);
            //std::cout<<"attrype : "<<type<<std::endl;
            if (type == "string") {
                //std::cout<<"saving custom string : "<<customAttr<<std::endl;
                MString value;
                value = argsList->asString(3);
                data->m_string_data.append(value);
                b_solv->set_custom_data_string(data, customAttr, value);
                //data->m_attr_type.append(customAttr);
                //char * chars = (char *)value.asChar();
                //void * char_ptr = (void *)chars;
                //b_solv->set_custom_data(customAttr, char_ptr);
            } else if (type == "double") {
                //std::cout<<"saving custom double : "<<customAttr<<std::endl;
                double value;
                value = argsList->asDouble(3);
                data->m_double_data.append(value);
                b_solv->set_custom_data_double(data, customAttr, value);
                //data->m_attr_type.append(customAttr);
                //void *val = &value;
                //b_solv->set_custom_data(customAttr, val);
            } else if (type == "int") {
                //std::cout<<"saving custom int : "<<customAttr<<std::endl;
                int value;
                value = argsList->asInt(3);
                //std::cout<<"argsList->get(3, value) -> value : "<<value<<std::endl;
                data->m_int_data.append(value);
                b_solv->set_custom_data_int(data, customAttr, value);
                //data->m_attr_type.append(customAttr);
                //std::cout<<"data->m_int_data : "<<data->m_int_data<<std::endl;
                //void *val = &value;
                //b_solv->set_custom_data(customAttr, val);
                //std::cout<<"b_solv->set_custom_data,static_cast<void*>(&value)) DONE!!!"<<std::endl;
            } else if (type == "vector") {
                //std::cout<<"saving custom vector : "<<customAttr<<std::endl;
                MVector value = MVector();
                value.x = argsList->asDouble(3);
                value.y = argsList->asDouble(4);
                value.z = argsList->asDouble(5);
                data->m_vector_data.append(value);
                b_solv->set_custom_data_vector(data, customAttr, value);
                //data->m_attr_type.append(customAttr);
                //MVector *MVecPtr = &value;
                //void * vec_ptr = static_cast<void*const>(MVecPtr);
                //b_solv->set_custom_data(customAttr, vec_ptr);
            }
            
        } else {
            
            if (attr == "velocity" ||
                attr == "position" ||
                attr == "angularVelocity")
            {
                MVector value;
                value.x = argsList->asDouble(3);
                value.y = argsList->asDouble(4);
                value.z = argsList->asDouble(5);
                //std::cout<<"vector argument : "<<value<<std::endl;
                setBulletVectorAttribute(rbName, attr, value);
            }
            
        }
        
        //cout<<value<<endl;
        setResult(MS::kSuccess);
        
    } else if ( isAttributeExist ) {
        MString exAttr;
        bool result = false;
        argParser->getFlagArgument("attributeExist", 0, exAttr);
        //std::cout<<"exAttr : "<<exAttr<<std::endl;
        MStringArray jobArgsArray = parseArguments(exAttr, ".");
        MString rbname = jobArgsArray[0];
        //std::cout<<"rbname : "<<rbname<<std::endl;
        MString attrToQuery = jobArgsArray[1];
        //std::cout<<"attrToQuery : "<<attrToQuery<<std::endl;
        MString attr = checkAttribute(attrToQuery);
        //std::cout<<"attr : "<<attr<<std::endl;
        if ( attr == "custom" ){ // here we check if user attribute by the name attrToQuery exists
            shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node();
            //char * queryAttr = (char*)attrToQuery.asChar();
            MString attrResult = b_solv->getAttrType(b_solv->getdata(rbname), attrToQuery);
            if (attrResult != "")
            //if (b_solv->attribute_exists(attrToQuery))
                result =  true;
            //std::cout<<result<<std::endl;;
            setResult(result);
        }

    } else if ( isAddAttr && isType ) {
        MString aAttr;
        argParser->getFlagArgument("addAttr", 0, aAttr);
        //std::cout<<"aAttr : "<<aAttr<<std::endl;
        MStringArray jobArgsArray = parseArguments(aAttr, ".");
        //std::cout<<"jobArgsArray : "<<jobArgsArray<<std::endl;
        MString rbname = jobArgsArray[0];
        MString attrAdded = jobArgsArray[1];
        //char *added = (char *)attrAdded.asChar();
        MString attrType;
        argParser->getFlagArgument("-type", 0, attrType);
        //char *type = (char *)attrType.asChar();
        //std::cout<<"attrType : "<<attrType<<std::endl;
        shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node();
        bSolverNode::m_custom_data *data = b_solv->getdata(rbname);
        data->m_attr_name.append(attrAdded);
        data->m_attr_type.append(attrType);
        b_solv->saveAttrType(data, attrAdded, attrType);
        //std::cout<<"attr "<<aAttr<<" added"<<std::endl;
        //std::cout<<"data->m_attr_type : "<<data->m_attr_type<<std::endl;
        //std::cout<<"data->m_attr_name : "<<data->m_attr_name<<std::endl;
        
    } else if ( isGetAttr) {
        MString gAttr;
        shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node();
        argParser->getFlagArgument("getAttr", 0, gAttr);
        
        //std::cout<<gAttr<<std::endl;
        MStringArray jobArgsArray = parseArguments(gAttr, ".");
        MString rbname = jobArgsArray[0];
        //std::cout<<"name : "<<rbname<<std::endl;
        if ( rbname == "" ) {
            MString errorMsg = "ERROR ! boing -getAttr must provide a rigid body name!";
            displayWarning(errorMsg, true);
            return MS::kFailure;
        }
        MString attr = checkAttribute(jobArgsArray[1]);
        //std::cout<<"attr = "<<attr<<std::endl;
        if ( attr=="velocity" || attr=="position" || attr=="angularVelocity" ) {
            //MVector result =
            MDoubleArray dResult = getBulletVectorAttribute(rbname, attr);
            setResult(dResult);
        } else if (attr == "contactPositions") {
            bSolverNode::m_custom_data *data = b_solv->getdata(rbname);
            MDoubleArray d_points = MDoubleArray();
            if ( data->m_contact_count > 0 ) {
                MPointArray points = data->m_contact_positions;
                for (int i=0; i<points.length();i++) {
                    d_points.append(points[i].x);
                    d_points.append(points[i].y);
                    d_points.append(points[i].z);
                }
            }
            setResult(d_points);
        } else if (attr == "contactGeos") {
            MStringArray contact_objects = MStringArray();
            bSolverNode::m_custom_data *data = b_solv->getdata(rbname);
            if ( data->m_contact_count > 0 ) {
                MStringArray contact_objects = data->m_contact_objects;
            }
            setResult(contact_objects);
        } else if (attr == "contactCount") {
            bSolverNode::m_custom_data *data = b_solv->getdata(rbname);
            int contact_count = data->m_contact_count;
            setResult(contact_count);
        } else if (attr == "name") {
            MStringArray result;
            MStringArray names = b_solv->get_all_keys();
            //std::cout<<"names : "<<names<<std::endl;
            //std::cout<<"b_solv->getdatalength() : "<<b_solv->getdatalength()<<std::endl;
            for(int i=0; i < names.length(); i++) {
                bSolverNode::m_custom_data *data = b_solv->getdata(names[i]);
                if ( NULL != data) {
                    //std::cout<<"data->name : "<<data->name<<std::endl;
                    //std::cout<<"data->m_initial_position: "<<data->m_initial_position<<std::endl;
                    result.append(data->name);
                }
            }
            setResult(result);
        } else if ( attr == "" ) {
            MString errorMsg = "ERROR ! boing -getAttr must provide an attribute name to query!";
            displayWarning(errorMsg, true);
            return MS::kFailure;
        } else if ( attr == "custom" ){ // here we handle user attributes
            MString customAttr = jobArgsArray[1];
            //char * custAttr = (char*)customAttr.asChar();
            //std::cout<<"customAttr :  "<<customAttr<<std::endl;
            MString type = b_solv->getAttrType(b_solv->getdata(rbname), customAttr);
            //bSolverNode::m_custom_data *data = b_solv->getdata(rbname);
            std::cout<<" type :  "<<type<<std::endl;
            if (type == "string") {
                //char * result = static_cast<char*>(b_solv->get_custom_data(customAttr));
                MString result = b_solv->get_custom_data_string(b_solv->getdata(rbname), customAttr);
                if (result != NULL) {
                    //std::cout<<"result : "<<result<<std::endl;
                    MString value(result);
                    setResult(value);
                } else {
                    displayError(MString("Error getting b_solv->get_custom_data_string(\"" + customAttr + "\")"));
                }
            } else if (type == "double") {
                //double *value = static_cast<double*>(b_solv->get_custom_data(customAttr));
                double value = b_solv->get_custom_data_double(b_solv->getdata(rbname), customAttr);
                setResult(value);
            } else if (type == "int") {
                //int *value = static_cast<int*>(b_solv->get_custom_data(customAttr));
                int value = b_solv->get_custom_data_int(b_solv->getdata(rbname), customAttr);
                setResult(value);
            } else if (type == "vector") {
                //void * result = b_solv->get_custom_data(customAttr);
                //MVector *vec_res = (MVector*)result;
                MVector result = b_solv->get_custom_data_vector(b_solv->getdata(rbname), customAttr);
                MDoubleArray value;
                value.append(result.x);
                value.append(result.y);
                value.append(result.z);
                setResult(value);
            }
        }
        
    } else if ( isCreate  ) {
        MString aArgument;
        argParser->getFlagArgument("-create", 0, aArgument);
        
        MStringArray createArgs = parseArguments(aArgument,";");
        int size = createArgs.length();
        MString inputShape;
        MString rbname = "dummyRb";
        MVector av;
        MVector vel;
        MVector pos;
        MVector rot;
        
        for (int i=0; i!=size; ++i) {
            MStringArray singleArg = parseArguments(createArgs[i],"=");
            //std::cout<<"singleArg : "<<singleArg<<std::endl;
            if (singleArg[0] == "name") {
                rbname = singleArg[1];
            } else if (singleArg[0] == "geo") {
                //geo
                inputShape = singleArg[1];
                //std::cout<<"geo = "<<inputShape<<std::endl;
            } else if (singleArg[0] == "vel") {
                //initialvelocity
                MStringArray velArray = parseArguments(singleArg[1], ",");
                vel = MVector(velArray[0].asDouble(),
                              velArray[1].asDouble(),
                              velArray[2].asDouble()
                              );
                //std::cout<<"velocity = "<<vel<<std::endl;
                
            } else if (singleArg[0] == "pos") {
                //initialposition
                MStringArray posArray = parseArguments(singleArg[1], ",");
                pos = MVector(posArray[0].asDouble(),
                              posArray[1].asDouble(),
                              posArray[2].asDouble()
                              );
                //std::cout<<"position = "<<pos<<std::endl;
                
            } else if (singleArg[0] == "rot") {
                //initialrotation
                MStringArray rotArray = parseArguments(singleArg[1], ",");
                rot = MVector(rotArray[0].asDouble(),
                              rotArray[1].asDouble(),
                              rotArray[2].asDouble()
                              );
                //std::cout<<"rotation = "<<rot<<std::endl;
                
            } else if (singleArg[0] == "av") {
                //initialAngularVelocity
                MStringArray avArray = parseArguments(singleArg[1], ",");
                av = MVector(avArray[0].asDouble(),
                             avArray[1].asDouble(),
                             avArray[2].asDouble()
                             );
                //std::cout<<"initialAngularVelocity = "<<av<<std::endl;
                
            } else {
                std::cout<<"Unrecognized parameter : "<<singleArg[0]<<std::endl;
            }
        }
        // create boing node
        shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node();
        MObject node = nameToNode(inputShape);
        float mass = 1.0f;
        MString tname = "boing";
        MStatus stat = b_solv->createNode(node, rbname, tname, pos, vel, rot, av, mass);
        if (MS::kSuccess == stat) {
            setResult(rbname);
        } else {
            MGlobal::displayError(MString("Something went wrong when trying to create rigidbody : " + rbname + " ."));
        }
        
    } else if ( isDelete  ) {
        MString aArgument;
        argParser->getFlagArgument("-delete", 0, aArgument);
        //std::cout<<"delete aArgument "<<aArgument<<std::endl;
        if (aArgument != "") {
            shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node();
            b_solv->deletedata(aArgument);
            MStatus stat = b_solv->delete_key(aArgument, -1);
            if (stat != MS::kSuccess) {
                std::cerr<<"error occurred deleting "<<aArgument<<" ."<<std::endl;
                setResult(1);
            }
        }
    } else if ( isExists ) {
        MString exArg;
        argParser->getFlagArgument("-exists", 0, exArg);
        //std::cout<<"exArg : "<<exArg<<std::endl;
        if (exArg != "") {
            shared_ptr<bSolverNode> b_solv = bSolverNode::get_bsolver_node();
            bSolverNode::m_custom_data *data = b_solv->getdata(exArg);
            int result = false;
            if ( NULL != data ) {
                //setResult ( data->name );
                result = true;
            }
            setResult(result);
        }
    }
    
    return MS::kSuccess;
}
예제 #19
0
	void Helper4::addVariableBSDF( const std::string& param_name_as, const std::string& param_type_as, const std::string& param_name_maya )
	{
		std::string param_value;
		const std::string plugName(param_name_maya);

		MString fullPlugName((m_nodename+"."+plugName).c_str());
		int connected = liquidmaya::ShaderMgr::getSingletonPtr()->convertibleConnection(fullPlugName.asChar());
		if( connected == 0 )
		{
			if( isType("color", param_type_as) )
			{
				MDoubleArray val; 
				val.setLength(3);
				IfMErrorWarn(MGlobal::executeCommand("getAttr (\""+fullPlugName+"\")", val));

				param_value = m_nodename+"_"+plugName;
				createColor3(m_assembly->colors(), param_value.c_str(), val[0], val[1], val[2]);
			}
			else if( isType("scalar", param_type_as) )
			{
				MDoubleArray val; 
				val.setLength(3);
				IfMErrorWarn(MGlobal::executeCommand("getAttr (\""+fullPlugName+"\")", val));

				//val contains (r,b,g) value, but I only use val[0] for 'scalar'
				MString strVal0;
				strVal0.set(val[0]);
				param_value = strVal0.asChar();
			}
			else {
				liquidMessage2(messageWarning,"only [color],[scalar] are handled for an unconnected plug in BSDF. "
					"the plug of %s is unhandled.", fullPlugName.asChar());
				param_value = "unhandled";
			}
		}
		else if(connected == 1)//the color plug is linked in.
		{
			if( isType("texture_instance", param_type_as) )
			{
				MStringArray srcPlug;
				IfMErrorWarn(MGlobal::executeCommand("listConnections -source true -plugs true \""+fullPlugName+"\"", srcPlug));
				assert(srcPlug.length()==1);
				MStringArray src;
				srcPlug[0].split('.',src);
				MString srcNode(src[0]);
				if( is2DTexture(srcNode) || is3DTexture(srcNode) )
				{
					//visitFile(srcNode.asChar());
					param_value = getTextureInstanceName(srcNode.asChar());
				}else{
					liquidMessage2(messageWarning,"type of [%s] is unhandled.(not 2Dtexture and 3Dtexture). [%s]", srcNode.asChar(), fullPlugName.asChar());
					param_value = "unhandled";
				}
			}
			else if( isType("bsdf", param_type_as) )
			{
				//bsdf0 value
				MString srcBSDFModel; 
				IfMErrorWarn(MGlobal::executeCommand("getAttr (\""+fullPlugName+"\")", srcBSDFModel));

				MStringArray srcPlug;
				IfMErrorWarn(MGlobal::executeCommand("listConnections -source true -plugs true \""+fullPlugName+"\"", srcPlug));
				assert(srcPlug.length()==1);
				MStringArray src;
				srcPlug[0].split('.',src);
				MString srcNode(src[0]);

				param_value = srcNode.asChar();
			}
			else{
				liquidMessage2(messageWarning,"only [texture_instance],[bsdf] are handled for a connected-in plug in BSDF."
					"the plug of %s is unhandled.", fullPlugName.asChar());
				param_value = "unhandled";
			}

		}else{// $(fullPlugName) is connected out
			// if $(fullPlugName) plug is connected out to "bsdf0"/"bsdf1" of a "bsdf_mix" node,
			// we also need to create this plug for appleseed

			// get destination node(s)
			MStringArray desNodePlug;
			IfMErrorWarn(MGlobal::executeCommand("listConnections -destination true -plugs true \""+fullPlugName+"\"", desNodePlug));
			
			// check whether $(fullPlugName) is connected to a BSDF node
			bool isConnectedToA_BSDFMixNode = false;
			MString desPlug;
			for(std::size_t i = 0; i< desNodePlug.length(); ++i)
			{
				MStringArray des;
				desNodePlug[i].split('.',des);
				MString desNode(des[0]);

				//destination node BSDF type
				MString desNodeBSDFType;
				IfMErrorWarn(MGlobal::executeCommand( "getAttr \""+desNode+".rmanShaderType\"", desNodeBSDFType));

				if(desNodeBSDFType == "bsdf_mix")
				{
					isConnectedToA_BSDFMixNode = true;
					desPlug = des[1];
				}
			}

			// if $(fullPlugName) is connected out to "bsdf0"/"bsdf1" of a "bsdf_mix" node
			// we also need to create this plug for appleseed
			if( isConnectedToA_BSDFMixNode && (desPlug=="bsdf0" ||desPlug=="bsdf1") )
			{
				if( isType("color", param_type_as) )
				{
					MDoubleArray val; 
					val.setLength(3);
					IfMErrorWarn(MGlobal::executeCommand("getAttr (\""+fullPlugName+"\")", val));

					param_value = m_nodename+"_"+plugName;
					createColor3(m_assembly->colors(), param_value.c_str(), val[0], val[1], val[2]);
				}
				else if( isType("scalar", param_type_as) )
				{
					MDoubleArray val; 
					val.setLength(3);
					IfMErrorWarn(MGlobal::executeCommand("getAttr (\""+fullPlugName+"\")", val));

					//val contains (r,b,g) value, but I only use val[0] for 'scalar'
					MString strVal0;
					strVal0.set(val[0]);
					param_value = strVal0.asChar();
				}
				else if( isType("texture_instance", param_type_as) )
				{
					MStringArray srcPlug;
					IfMErrorWarn(MGlobal::executeCommand("listConnections -source true -plugs true \""+fullPlugName+"\"", srcPlug));
					assert(srcPlug.length()==1);
					MStringArray src;
					srcPlug[0].split('.',src);
					MString srcNode(src[0]);
					if( is2DTexture(srcNode) || is3DTexture(srcNode) )
					{
						//visitFile(srcNode.asChar());
						param_value = getTextureInstanceName(srcNode.asChar());
					}else{
						liquidMessage2(messageWarning,"type of [%s] is unhandled.(not 2Dtexture and 3Dtexture). [%s]", srcNode.asChar(), fullPlugName.asChar());
						param_value = "unhandled";
					}
				}
				else {
					liquidMessage2(messageWarning,"only [color],[scalar],[texture_instance] are handled for an connected-out plug in BSDF. "
						"the plug of %s is unhandled.", fullPlugName.asChar());
					param_value = "unhandled";
				}
			}//if( nodetype=="bsdf_mix" && (desPlug=="bsdf0" ||desPlug=="bsdf1") )
			else {
				liquidMessage2(messageWarning,"[%s] is connected out. But not connected to brdf node, or not brdf0/brdf1 of a brdf node."
					" So I don't create the value for this plug.", fullPlugName.asChar());
			}
		}
		//
		addVariableBSDF(param_name_as, param_value);
	}
    // Parse the options String
    void ExportOptions::set ( const MString& optionsString )
    {
        // Reset everything to the default value
        mBakeTransforms = false;
        mRelativePaths = true;

        /** True, if the texture files should be copied to the destination folder. */
        mCopyTextures = false;
       
        mIsSampling = false;
        mCurveConstrainSampling = false;
        mRemoveStaticCurves = true;
        mExportCameraAsLookat = false;
        mExportTriangles = false;
        
        mExportPolygonMeshes = true;
        mExportLights = true;
        mExportCameras = true;
        mExportMaterialsOnly = false;
        mExportReferencedMaterials = true;
        mExportJointsAndSkin = true;
        mExportAnimations = true;
        mExportInvisibleNodes = false;
        mExportDefaultCameras = false;
        mExportNormals = true;
        mExportNormalsPerVertex = true;
        mExportTexCoords = true;
        mExportVertexColors = true;
        mExportVertexColorsPerVertex = true;
        mExportTangents = false;
        mExportTexTangents = false;
        mExportXRefs = true;
        mDereferenceXRefs = true;
        mCameraXFov = false;
        mCameraYFov = true;
        mDoublePrecision = false;
        mExportCgfxFileReferences = true;

        // Parse option String
        if ( optionsString.length() > 0 )
        {
            MStringArray optionList;
            optionsString.split ( ';', optionList );
            uint optionCount = optionList.length();

            for ( uint i = 0; i < optionCount; ++i )
            {
                MString& currentOption = optionList[i];

                // Process option name and values.
                MStringArray decomposedOption;
                currentOption.split ( '=', decomposedOption );
                MString& optionName = decomposedOption[0];

                // For boolean values, the value is assumed to be true
                // if omitted.
                bool value = true;

                if ( decomposedOption.length() > 1 &&
                        decomposedOption[1] != "true" &&
                        decomposedOption[1] != "1" )
                    value = false;

                // Process options.
                if ( optionName == "bakeTransforms" ) mBakeTransforms = value;
                else if ( optionName == "relativePaths" ) mRelativePaths = value;
                else if ( optionName == "exportTriangles" ) mExportTriangles = value;
                else if ( optionName == "cgfxFileReferences" ) mExportCgfxFileReferences = value;
                else if ( optionName == "copyTextures" ) mCopyTextures = value;
                else if ( optionName == "exportPolygonMeshes" ) mExportPolygonMeshes = value;
                else if ( optionName == "exportLights" ) mExportLights = value;
                else if ( optionName == "exportCameras" ) mExportCameras = value;
                else if ( optionName == "exportJointsAndSkin" ) mExportJointsAndSkin = value;
                else if ( optionName == "exportMaterialsOnly" ) mExportMaterialsOnly = value;
                else if ( optionName == "exportReferencedMaterials" ) mExportReferencedMaterials = value;
                else if ( optionName == "exportAnimations" ) mExportAnimations = value;
                else if ( optionName == "exportInvisibleNodes" ) mExportInvisibleNodes = value;
                else if ( optionName == "exportDefaultCameras" ) mExportDefaultCameras = value;
                else if ( optionName == "exportNormals" ) mExportNormals = value;
                else if ( optionName == "exportNormalsPerVertex" ) mExportNormalsPerVertex = value;
                else if ( optionName == "exportTexCoords" ) mExportTexCoords = value;
                else if ( optionName == "exportVertexColors" ) mExportVertexColors = value;
                else if ( optionName == "exportVertexColorsPerVertex" ) mExportVertexColorsPerVertex = value;
                else if ( optionName == "exportTangents" ) mExportTangents = value;
                else if ( optionName == "exportTexTangents" ) mExportTexTangents = value;
                else if ( optionName == "exportCameraAsLookat" ) mExportCameraAsLookat = value;
                else if ( optionName == "cameraXFov" ) mCameraXFov = value;
                else if ( optionName == "cameraYFov" ) mCameraYFov = value;
                else if ( optionName == "doublePrecision" ) mDoublePrecision = value;
                else if ( optionName == "isSampling" ) mIsSampling = value;
                else if ( optionName == "curveConstrainSampling" ) mCurveConstrainSampling = value;
                else if ( optionName == "removeStaticCurves" ) mRemoveStaticCurves = value;
                else if ( optionName == "exportXRefs" ) mExportXRefs = value;
                else if ( optionName == "dereferenceXRefs" ) mDereferenceXRefs = value;
            }
        }

        if ( !mIsSampling )
        {
            AnimationHelper::generateSamplingFunction();
        }
    }
예제 #21
0
	// Load material data
	MStatus Material::load(MFnDependencyNode* pShader,MStringArray& uvsets,ParamList& params)
	{
		MStatus stat;
		clear();
		//read material name, adding the requested prefix
		MString tmpStr = params.matPrefix;
		if (tmpStr != "")
			tmpStr += "/";
		tmpStr += pShader->name();
		MStringArray tmpStrArray;
		tmpStr.split(':',tmpStrArray);
		m_name = "";
		for (int i=0; i<tmpStrArray.length(); i++)
		{
			m_name += tmpStrArray[i];
			if (i < tmpStrArray.length()-1)
				m_name += "_";
		}

		//check if we want to export with lighting off option
		m_lightingOff = params.lightingOff;

		// GET MATERIAL DATA

		// Check material type
		if (pShader->object().hasFn(MFn::kPhong))
		{
			stat = loadPhong(pShader);
		}
		else if (pShader->object().hasFn(MFn::kBlinn))
		{
			stat = loadBlinn(pShader);
		}
		else if (pShader->object().hasFn(MFn::kLambert))
		{
			stat = loadLambert(pShader);
		}
		else if (pShader->object().hasFn(MFn::kPluginHwShaderNode))
		{
			stat = loadCgFxShader(pShader);
		}
		else
		{
			stat = loadSurfaceShader(pShader);
		}

		// Get textures data
		MPlugArray colorSrcPlugs;
		MPlugArray texSrcPlugs;
		MPlugArray placetexSrcPlugs;
		if (m_isTextured)
		{
			// Translate multiple textures if material is multitextured
			if (m_isMultiTextured)
			{
				// Get layered texture node
				MFnDependencyNode* pLayeredTexNode = NULL;
				if (m_type == MT_SURFACE_SHADER)
					pShader->findPlug("outColor").connectedTo(colorSrcPlugs,true,false);
				else
					pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false);
				for (int i=0; i<colorSrcPlugs.length(); i++)
				{
					if (colorSrcPlugs[i].node().hasFn(MFn::kLayeredTexture))
					{
						pLayeredTexNode = new MFnDependencyNode(colorSrcPlugs[i].node());
						continue;
					}
				}

				// Get inputs to layered texture
				MPlug inputsPlug = pLayeredTexNode->findPlug("inputs");

				// Scan inputs and export textures
				for (int i=inputsPlug.numElements()-1; i>=0; i--)
				{
					MFnDependencyNode* pTextureNode = NULL;
					// Search for a connected texture
					inputsPlug[i].child(0).connectedTo(colorSrcPlugs,true,false);
					for (int j=0; j<colorSrcPlugs.length(); j++)
					{
						if (colorSrcPlugs[j].node().hasFn(MFn::kFileTexture))
						{
							pTextureNode = new MFnDependencyNode(colorSrcPlugs[j].node());
							continue;
						}
					}

					// Translate the texture if it was found
					if (pTextureNode)
					{
						// Get blend mode
						TexOpType opType;
						short bm;
						inputsPlug[i].child(2).getValue(bm);
						switch(bm)
						{				
						case 0:
							opType = TOT_REPLACE;
							break;
						case 1:
							opType = TOT_ALPHABLEND;
							break;				
						case 4:
							opType = TOT_ADD;
							break;
						case 6:
							opType = TOT_MODULATE;
							break;
						default:
							opType = TOT_MODULATE;
						}

						stat = loadTexture(pTextureNode,opType,uvsets,params);
						delete pTextureNode;
						if (MS::kSuccess != stat)
						{
							std::cout << "Error loading layered texture\n";
							std::cout.flush();
							delete pLayeredTexNode;
							return MS::kFailure;
						}
					}
				}
				if (pLayeredTexNode)
					delete pLayeredTexNode;
			}
			// Else translate the single texture
			else
			{
				// Get texture node
				MFnDependencyNode* pTextureNode = NULL;
				if (m_type == MT_SURFACE_SHADER)
					pShader->findPlug("outColor").connectedTo(colorSrcPlugs,true,false);
				else
					pShader->findPlug("color").connectedTo(colorSrcPlugs,true,false);
				for (int i=0; i<colorSrcPlugs.length(); i++)
				{
					if (colorSrcPlugs[i].node().hasFn(MFn::kFileTexture))
					{
						pTextureNode = new MFnDependencyNode(colorSrcPlugs[i].node());
						continue;
					}
				}
				if (pTextureNode)
				{
					TexOpType opType = TOT_MODULATE;
					stat = loadTexture(pTextureNode,opType,uvsets,params);
					delete pTextureNode;
					if (MS::kSuccess != stat)
					{
						std::cout << "Error loading texture\n";
						std::cout.flush();
						return MS::kFailure;
					}
				}
			}
		}

		return MS::kSuccess;
	}
예제 #22
0
	MStatus Submesh::load(std::vector<face>& faces, std::vector<vertexInfo>& vertInfo, MFloatPointArray& points, 
		MFloatVectorArray& normals, MStringArray& texcoordsets,ParamList& params,bool opposite)
	{
		//save uvsets info
		for (int i=m_uvsets.size(); i<texcoordsets.length(); i++)
		{
			uvset uv;
			uv.size = 2;
			m_uvsets.push_back(uv);
		}
		//iterate over faces array, to retrieve vertices info
		for (int i=0; i<faces.size(); i++)
		{
			face newFace;
			// if we are using shared geometry, indexes refer to the vertex buffer of the whole mesh
			if (params.useSharedGeom)
			{
				if(opposite)
				{	// reverse order of face vertices for correct culling
					newFace.v[0] = faces[i].v[2];
					newFace.v[1] = faces[i].v[1];
					newFace.v[2] = faces[i].v[0];
				}
				else
				{
					newFace.v[0] = faces[i].v[0];
					newFace.v[1] = faces[i].v[1];
					newFace.v[2] = faces[i].v[2];
				}
			}
			// otherwise we create a vertex buffer for this submesh
			else
			{	// faces are triangles, so retrieve index of the three vertices
				for (int j=0; j<3; j++)
				{
					vertex v;
					vertexInfo vInfo = vertInfo[faces[i].v[j]];
					// save vertex coordinates
					v.x = points[vInfo.pointIdx].x;
					v.y = points[vInfo.pointIdx].y;
					v.z = points[vInfo.pointIdx].z;
					// save vertex normal
					if (opposite)
					{
						v.n.x = -normals[vInfo.normalIdx].x;
						v.n.y = -normals[vInfo.normalIdx].y;
						v.n.z = -normals[vInfo.normalIdx].z;
					}
					else
					{
						v.n.x = normals[vInfo.normalIdx].x;
						v.n.y = normals[vInfo.normalIdx].y;
						v.n.z = normals[vInfo.normalIdx].z;
					}
					v.n.normalize();
					// save vertex color
					v.r = vInfo.r;
					v.g = vInfo.g;
					v.b = vInfo.b;
					v.a = vInfo.a;
					// save vertex bone assignements
					for (int k=0; k<vInfo.vba.size(); k++)
					{
						vba newVba;
						newVba.jointIdx = vInfo.jointIds[k];
						newVba.weight = vInfo.vba[k];
						v.vbas.push_back(newVba);
					}
					// save texture coordinates
					for (int k=0; k<vInfo.u.size(); k++)
					{
						texcoords newTexCoords;
						newTexCoords.u = vInfo.u[k];
						newTexCoords.v = vInfo.v[k];
						newTexCoords.w = 0;
						v.texcoords.push_back(newTexCoords);
					}
					// add newly created vertex to vertex list
					m_vertices.push_back(v);
					if (opposite)	// reverse order of face vertices to get correct culling
						newFace.v[2-j] = m_vertices.size() - 1;
					else
						newFace.v[j] = m_vertices.size() - 1;
				}
			}
			m_faces.push_back(newFace);
		}
		// set use32bitIndexes flag
		if (params.useSharedGeom || (m_vertices.size() > 65535) || (m_faces.size() > 65535))
			m_use32bitIndexes = true;
		else
			m_use32bitIndexes = false;
		return MS::kSuccess;
	}
예제 #23
0
MStatus MayaToCorona::doIt( const MArgList& args)
{
    MStatus stat = MStatus::kSuccess;
    std::unique_ptr<MayaTo::CmdArgs> cmdArgs(new MayaTo::CmdArgs);

    MArgDatabase argData(syntax(), args);

    if (argData.isFlagSet("-version", &stat))
    {
        MStringArray res;
        for (auto v : getFullVersionString())
            res.append(v.c_str());
        setResult(res);

        return MS::kSuccess;
    }

    MayaTo::MayaToWorld::WorldRenderState rstate = MayaTo::getWorldPtr()->renderState;
    if (argData.isFlagSet("-state", &stat))
    {
        if (rstate == MayaTo::MayaToWorld::RSTATETRANSLATING)
            setResult("rstatetranslating");
        if (rstate == MayaTo::MayaToWorld::RSTATERENDERING)
            setResult("rstaterendering");
        if (rstate == MayaTo::MayaToWorld::RSTATEDONE)
            setResult("rstatedone");
        if (rstate == MayaTo::MayaToWorld::RSTATENONE)
            setResult("rstatenone");
        if (rstate == MayaTo::MayaToWorld::RSTATESTOPPED)
            setResult("rstatestopped");
        return MS::kSuccess;
    }

    MGlobal::displayInfo("Executing mayaToCorona...");
    setLogLevel();

    if (argData.isFlagSet("-canDoIPR", &stat))
    {
        if(MayaTo::getWorldPtr()->canDoIPR())
            setResult("yes");
        else
            setResult("no");
        return MS::kSuccess;
    }

    if ( argData.isFlagSet("-stopIpr", &stat))
    {
        Logging::debug(MString("-stopIpr"));
        EventQueue::Event e;
        e.type = EventQueue::Event::IPRSTOP;
        theRenderEventQueue()->push(e);
        return MS::kSuccess;
    }

    if ( argData.isFlagSet("-pauseIpr", &stat))
    {
        Logging::debug(MString("-pauseIpr"));
        Logging::debug(MString("-stopIpr"));
        EventQueue::Event e;
        e.type = EventQueue::Event::IPRPAUSE;
        theRenderEventQueue()->push(e);
        return MS::kSuccess;
    }

    if (argData.isFlagSet("-usrDataString", &stat))
    {
        Logging::debug(MString("-usrDataString"));
        argData.getFlagArgument("-usrDataString", 0, cmdArgs->userDataString);
    }

    if (argData.isFlagSet("-usrDataInt", &stat))
    {
        Logging::debug(MString("-usrDataInt"));
        argData.getFlagArgument("-usrDataInt", 0, cmdArgs->userDataInt);
    }

    if (argData.isFlagSet("-usrDataFloat", &stat))
    {
        Logging::debug(MString("-usrDataFloat"));
        argData.getFlagArgument("-usrDataFloat", 0, cmdArgs->userDataFloat);
    }

    if (argData.isFlagSet("-usrEvent", &stat))
    {
        Logging::debug(MString("-usrEvent"));
        argData.getFlagArgument("-usrEvent", 0, cmdArgs->userEvent);

        EventQueue::Event e;
        e.cmdArgsData = std::move(cmdArgs);
        e.type = EventQueue::Event::USER;
        theRenderEventQueue()->push(e);
        return MS::kSuccess;
    }

    // I have to request useRenderRegion here because as soon the command is finished, what happens immediatly after the command is
    // put into the queue, the value is set back to false.
    MObject drg = objectFromName("defaultRenderGlobals");
    MFnDependencyNode drgfn(drg);
    cmdArgs->useRenderRegion = drgfn.findPlug("useRenderRegion").asBool();

    cmdArgs->renderType = MayaTo::MayaToWorld::WorldRenderType::UIRENDER;
    if (MGlobal::mayaState() == MGlobal::kBatch)
        cmdArgs->renderType = MayaTo::MayaToWorld::WorldRenderType::BATCHRENDER;

    if ( argData.isFlagSet("-startIpr", &stat))
    {
        Logging::debug(MString("-startIpr"));
        cmdArgs->renderType = MayaTo::MayaToWorld::WorldRenderType::IPRRENDER;
    }

    if (argData.isFlagSet("-width", &stat))
    {
        argData.getFlagArgument("-width", 0, cmdArgs->width);
        Logging::debug(MString("width: ") + cmdArgs->width);
    }

    if (argData.isFlagSet("-height", &stat))
    {
        argData.getFlagArgument("-height", 0, cmdArgs->height);
        Logging::debug(MString("height: ") + cmdArgs->height);
    }

    if ( argData.isFlagSet("-camera", &stat))
    {
        MDagPath camera;
        MSelectionList selectionList;
        argData.getFlagArgument("-camera", 0, selectionList);
        stat = selectionList.getDagPath(0, camera);
        camera.extendToShape();
        Logging::debug(MString("camera: ") + camera.fullPathName());
        cmdArgs->cameraDagPath = camera;
    }

    EventQueue::Event e;
    e.cmdArgsData = std::move(cmdArgs);
    e.type = EventQueue::Event::INITRENDER;
    theRenderEventQueue()->push(e);

    //
    if (MGlobal::mayaState() == MGlobal::kBatch)
    {
        RenderQueueWorker::startRenderQueueWorker();
    }
    return MStatus::kSuccess;
}
MStatus lrutils::loadGeoReference(MString geoFilePath, MString geoName, MString & name, MObject & geoObj) {
    MStatus status = MS::kFailure;

    MString projPath = MGlobal::executeCommandStringResult(MString("workspace -q -rd;"),false,false);
    MString relativePath = geoFilePath.substring(2,geoFilePath.numChars() - 1);

    //assemble the full file path of the geometry file
    MString fullGeoPath = projPath + relativePath;

    //load the geometry file as a reference into the current scene
    //check to see if the referenced file has already been used
    MStringArray refNodeList;
    status = MFileIO::getReferences(refNodeList, true);
    MyCheckStatus(status, "getReferences failed");
    int numReferences = 0;
    for(unsigned int i = 0; i < refNodeList.length(); i++) {
        MString tmp = refNodeList[i];
        string tmp1 = tmp.asChar();
        string tmp2 = fullGeoPath.asChar();
        if(std::string::npos != tmp1.find(tmp2))
            numReferences++;
    }
    string str (geoFilePath.asChar());
    string key ("/");
    size_t found = str.rfind(key);
    string fileName = str.substr(found+1,str.length()-found-4);
    string fileNamespace;
    if(numReferences > 0) {
        stringstream tmp;
        tmp << fileName << (numReferences+1);
        fileNamespace = tmp.str();
    } else { fileNamespace = fileName; }

    {
        stringstream tmp;
        tmp << "file -r -type \"mayaAscii\" -gl -loadReferenceDepth \"all\" -namespace \"" << fileNamespace.c_str() << "\" -options \"v=0\" \"" << fullGeoPath.asChar() << "\";";
        MString referenceCommand = MString(tmp.str().c_str());
        MGlobal::executeCommand(referenceCommand);
    }
    
    //get the referenced geometry transform node and add the metaParent
    //attribute to it
    MSelectionList selection;
    if(numReferences > 0) {
        name += (boost::lexical_cast<string>(numReferences+1)).c_str();
    }
    stringstream geoRefName;
    geoRefName << fileNamespace << ":" << geoName;
    MString mGeoRefName = MString(geoRefName.str().c_str());
    status = selection.add( mGeoRefName, true );
    MyCheckStatusReturn(status, "add geoRefName "+mGeoRefName+" to selection failed.");

    if(selection.length() )
        selection.getDependNode(0, geoObj);

    MFnTransform transformFn;
    transformFn.setObject(geoObj);
    MFnMessageAttribute mAttr;
    MObject transformAttr = mAttr.create("metaParent", "metaParent");
    transformFn.addAttribute(transformAttr);

    if( !geoObj.isNull() )
        status = MS::kSuccess;

    return status;
}
예제 #25
0
MStatus skinClusterWeights::redoIt()
{
    MStatus status;
    unsigned int ptr = 0;
	
    MSelectionList selList;
    int geomLen = geometryArray.length();
    fDagPathArray.setLength(geomLen);
    fComponentArray.setLength(geomLen);
    fInfluenceIndexArrayPtrArray = new MIntArray[geomLen];
    fWeightsPtrArray = new MDoubleArray[geomLen];

    for (int i = 0; i < geomLen; i++) {
	MDagPath dagPath;
	MObject  component;
	
	selList.clear();
	selList.add(geometryArray[i]);
	MStatus status = selList.getDagPath(0, dagPath, component);
	if (status != MS::kSuccess) {
	    continue;
	}
	if (component.isNull()) dagPath.extendToShape();

	MObject skinCluster = findSkinCluster(dagPath);
	if (!isSkinClusterIncluded(skinCluster)) {
	    continue;
	}

	MFnSkinCluster skinClusterFn(skinCluster, &status);
	if (status != MS::kSuccess) {
	    continue; 
	}

	MIntArray influenceIndexArray;
	populateInfluenceIndexArray(skinClusterFn, influenceIndexArray);

	unsigned numInf = influenceIndexArray.length();
	if (numInf == 0) continue;
	  
	unsigned numCV = 0;
	if (dagPath.node().hasFn(MFn::kMesh)) {
	    MItMeshVertex polyIter(dagPath, component, &status);
	    if (status == MS::kSuccess) {
		numCV = polyIter.count();
	    } 
	} else if (dagPath.node().hasFn(MFn::kNurbsSurface)) {
	    MItSurfaceCV nurbsIter(dagPath, component, true, &status);
	    if (status == MS::kSuccess) {
		while (!nurbsIter.isDone()) {
		    numCV++;
		    nurbsIter.next();
		}
	    }
	} else if (dagPath.node().hasFn(MFn::kNurbsCurve)) {
	    MItCurveCV curveIter(dagPath, component, &status);
	    if (status == MS::kSuccess) {
		while (!curveIter.isDone()) {
		    numCV++;
		    curveIter.next();
		}
	    }
	}
	unsigned numEntry = numCV * numInf;

	if (numEntry > 0) {
	    MDoubleArray weights(numEntry);
	    unsigned int numWeights = weightArray.length();
	    if (assignAllToSingle) {
		if (numInf <= numWeights) {
		    for (unsigned j = 0; j < numEntry; j++) {
			weights[j] = weightArray[j % numInf];
		    }
		} else {
		    MGlobal::displayError("Not enough weights specified\n");
		    return MS::kFailure;
		}
	    } else {
		for (unsigned j = 0; j < numEntry; j++, ptr++) {
		    if (ptr < numWeights) {
			weights[j] = weightArray[ptr];
		    } else {
			MGlobal::displayError("Not enough weights specified\n");
			return MS::kFailure;
		    }
		}
	    }

	    // support for undo
	    fDagPathArray[i] = dagPath;
	    fComponentArray[i] = component;
	    fInfluenceIndexArrayPtrArray[i] = influenceIndexArray;
	    MDoubleArray oldWeights;
	    skinClusterFn.getWeights(dagPath, component, influenceIndexArray, oldWeights);
	    fWeightsPtrArray[i] = oldWeights;
	    
	    skinClusterFn.setWeights(dagPath, component, influenceIndexArray, weights);
	}
    }
    return MS::kSuccess;
}
예제 #26
0
MStatus AbcExport::doIt(const MArgList & args)
{
try
{
    MStatus status;

    MTime oldCurTime = MAnimControl::currentTime();

    MArgParser argData(syntax(), args, &status);

    if (argData.isFlagSet("help"))
    {
        MGlobal::displayInfo(util::getHelpText());
        return MS::kSuccess;
    }

    bool verbose = argData.isFlagSet("verbose");

    // If skipFrame is true, when going through the playback range of the
    // scene, as much frames are skipped when possible.  This could cause
    // a problem for, time dependent solutions like
    // particle system / hair simulation
    bool skipFrame = true;
    if (argData.isFlagSet("dontSkipUnwrittenFrames"))
        skipFrame = false;

    double startEvaluationTime = DBL_MAX;
    if (argData.isFlagSet("preRollStartFrame"))
    {
        double startAt = 0.0;
        argData.getFlagArgument("preRollStartFrame", 0, startAt);
        startEvaluationTime = startAt;
    }

    unsigned int jobSize = argData.numberOfFlagUses("jobArg");

    if (jobSize == 0)
        return status;

    // the frame range we will be iterating over for all jobs,
    // includes frames which are not skipped and the startAt offset
    std::set<double> allFrameRange;

    // this will eventually hold only the animated jobs.
    // its a list because we will be removing jobs from it
    std::list < AbcWriteJobPtr > jobList;

    for (unsigned int jobIndex = 0; jobIndex < jobSize; jobIndex++)
    {
        JobArgs jobArgs;
        MArgList jobArgList;
        argData.getFlagArgumentList("jobArg", jobIndex, jobArgList);
        MString jobArgsStr = jobArgList.asString(0);
        MStringArray jobArgsArray;

        {
            // parse the job arguments
            // e.g. -perFrameCallbackMel "print \"something\"" will be splitted to
            //    [0] -perFrameCallbackMel
            //    [1] print "something"
            enum State {
                kArgument,               // parsing an argument (not quoted)
                kDoubleQuotedString,     // parsing a double quoted string
                kSingleQuotedString,     // parsing a single quoted string
            };

            State state = kArgument;
            MString stringBuffer;
            for (unsigned int charIdx = 0; charIdx < jobArgsStr.numChars();
                charIdx++)
            {
                MString ch = jobArgsStr.substringW(charIdx, charIdx);
                switch (state)
                {
                case kArgument:
                    if (ch == " ")
                    {
                        // space terminates the current argument
                        if (stringBuffer.length() > 0) {
                            jobArgsArray.append(stringBuffer);
                            stringBuffer.clear();
                        }
                        // goto another argument
                        state = kArgument;
                    }
                    else if (ch == "\"")
                    {
                        if (stringBuffer.length() > 0)
                        {
                            // double quote is part of the argument
                            stringBuffer += ch;
                        }
                        else
                        {
                            // goto double quoted string
                            state = kDoubleQuotedString;
                        }
                    }
                    else if (ch == "'")
                    {
                        if (stringBuffer.length() > 0)
                        {
                            // single quote is part of the argument
                            stringBuffer += ch;
                        }
                        else
                        {
                            // goto single quoted string
                            state = kSingleQuotedString;
                        }
                    }
                    else
                    {
                        stringBuffer += ch;
                    }
                break;

                case kDoubleQuotedString:
                    // double quote terminates the current string
                    if (ch == "\"")
                    {
                        jobArgsArray.append(stringBuffer);
                        stringBuffer.clear();
                        state = kArgument;
                    }
                    else if (ch == "\\")
                    {
                        // escaped character
                        MString nextCh = (++charIdx < jobArgsStr.numChars())
                            ? jobArgsStr.substringW(charIdx, charIdx) : "\\";
                        if (nextCh == "n")       stringBuffer += "\n";
                        else if (nextCh == "t")  stringBuffer += "\t";
                        else if (nextCh == "r")  stringBuffer += "\r";
                        else if (nextCh == "\\") stringBuffer += "\\";
                        else if (nextCh == "'")  stringBuffer += "'";
                        else if (nextCh == "\"") stringBuffer += "\"";
                        else                     stringBuffer += nextCh;
                    }
                    else
                    {
                        stringBuffer += ch;
                    }
                break;

                case kSingleQuotedString:
                    // single quote terminates the current string
                    if (ch == "'")
                    {
                        jobArgsArray.append(stringBuffer);
                        stringBuffer.clear();
                        state = kArgument;
                    }
                    else if (ch == "\\")
                    {
                        // escaped character
                        MString nextCh = (++charIdx < jobArgsStr.numChars())
                            ? jobArgsStr.substringW(charIdx, charIdx) : "\\";
                        if (nextCh == "n")       stringBuffer += "\n";
                        else if (nextCh == "t")  stringBuffer += "\t";
                        else if (nextCh == "r")  stringBuffer += "\r";
                        else if (nextCh == "\\") stringBuffer += "\\";
                        else if (nextCh == "'")  stringBuffer += "'";
                        else if (nextCh == "\"") stringBuffer += "\"";
                        else                     stringBuffer += nextCh;
                    }
                    else
                    {
                        stringBuffer += ch;
                    }
                break;
                }
            }

            // the rest of the argument
            if (stringBuffer.length() > 0)
            {
                jobArgsArray.append(stringBuffer);
            }
        }

        // the frame range within this job
        std::vector< FrameRangeArgs > frameRanges(1);
        frameRanges.back().startTime = oldCurTime.value();
        frameRanges.back().endTime = oldCurTime.value();
        frameRanges.back().strideTime = 1.0;

        bool hasRange = false;
        bool hasRoot = false;
        bool sampleGeo  = true; // whether or not to subsample geometry
        std::string fileName;
        bool asOgawa = true;

        unsigned int numJobArgs = jobArgsArray.length();
        for (unsigned int i = 0; i < numJobArgs; ++i)
        {
            MString arg = jobArgsArray[i];
            arg.toLowerCase();

            if (arg == "-f" || arg == "-file")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError("File incorrectly specified.");
                    return MS::kFailure;
                }
                fileName = jobArgsArray[++i].asUTF8();
            }

            else if (arg == "-fr" || arg == "-framerange")
            {
                if (i+2 >= numJobArgs || !jobArgsArray[i+1].isDouble() ||
                    !jobArgsArray[i+2].isDouble())
                {
                    MGlobal::displayError("Frame Range incorrectly specified.");
                    return MS::kFailure;
                }

                // this is not the first -frameRange argument, we are going
                // to add one more frame range to the frame range array.
                if (hasRange)
                {
                    frameRanges.push_back(FrameRangeArgs());
                }

                hasRange = true;
                frameRanges.back().startTime = jobArgsArray[++i].asDouble();
                frameRanges.back().endTime = jobArgsArray[++i].asDouble();

                // make sure start frame is smaller or equal to endTime
                if (frameRanges.back().startTime > frameRanges.back().endTime)
                {
                    std::swap(frameRanges.back().startTime,
                        frameRanges.back().endTime);
                }
            }

            else if (arg == "-frs" || arg == "-framerelativesample")
            {
                if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble())
                {
                    MGlobal::displayError(
                        "Frame Relative Sample incorrectly specified.");
                    return MS::kFailure;
                }
                frameRanges.back().shutterSamples.insert(
                    jobArgsArray[++i].asDouble());
            }

            else if (arg == "-nn" || arg == "-nonormals")
            {
                jobArgs.noNormals = true;
            }

            else if (arg == "-pr" || arg == "-preroll")
            {
                frameRanges.back().preRoll = true;
            }

            else if (arg == "-ro" || arg == "-renderableonly")
            {
                jobArgs.excludeInvisible = true;
            }

            else if (arg == "-s" || arg == "-step")
            {
                if (i+1 >= numJobArgs || !jobArgsArray[i+1].isDouble())
                {
                    MGlobal::displayError("Step incorrectly specified.");
                    return MS::kFailure;
                }
                frameRanges.back().strideTime = jobArgsArray[++i].asDouble();
            }

            else if (arg == "-sl" || arg == "-selection")
            {
                jobArgs.useSelectionList = true;
            }

            else if (arg == "-sn" || arg == "-stripnamespaces")
            {
                if (i+1 >= numJobArgs || !jobArgsArray[i+1].isUnsigned())
                {
                    // the strip all namespaces case
                    // so we pick a very LARGE number
                    jobArgs.stripNamespace = 0xffffffff;
                }
                else
                {
                    jobArgs.stripNamespace = jobArgsArray[++i].asUnsigned();
                }
            }

            else if (arg == "-uv" || arg == "-uvwrite")
            {
                jobArgs.writeUVs = true;
            }

            else if (arg == "-wcs" || arg == "-writecolorsets")
            {
                jobArgs.writeColorSets = true;
            }

            else if (arg == "-wfs" || arg == "-writefacesets")
            {
                jobArgs.writeFaceSets = true;
            }

            else if (arg == "-wfg" || arg == "-wholeframegeo")
            {
                sampleGeo = false;
            }

            else if (arg == "-ws" || arg == "-worldspace")
            {
                jobArgs.worldSpace = true;
            }

            else if (arg == "-wuvs" || arg == "-writeuvsets")
            {
                jobArgs.writeUVSets = true;
            }

            else if (arg == "-wv" || arg == "-writevisibility")
            {
                jobArgs.writeVisibility = true;
            }

            else if (arg == "-mfc" || arg == "-melperframecallback")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "melPerFrameCallback incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.melPerFrameCallback = jobArgsArray[++i].asChar();
            }

            else if (arg == "-pfc" || arg == "-pythonperframecallback")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "pythonPerFrameCallback incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.pythonPerFrameCallback = jobArgsArray[++i].asChar();
            }

            else if (arg == "-mpc" || arg == "-melpostjobcallback")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "melPostJobCallback incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.melPostCallback = jobArgsArray[++i].asChar();
            }

            else if (arg == "-ppc" || arg == "-pythonpostjobcallback")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "pythonPostJobCallback incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.pythonPostCallback = jobArgsArray[++i].asChar();
            }

            // geomArbParams - attribute filtering stuff
            else if (arg == "-atp" || arg == "-attrprefix")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "attrPrefix incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.prefixFilters.push_back(jobArgsArray[++i].asChar());
            }

            else if (arg == "-a" || arg == "-attr")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "attr incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.attribs.insert(jobArgsArray[++i].asChar());
            }

            // userProperties - attribute filtering stuff
            else if (arg == "-uatp" || arg == "-userattrprefix")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "userAttrPrefix incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.userPrefixFilters.push_back(jobArgsArray[++i].asChar());
            }

            else if (arg == "-u" || arg == "-userattr")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "userAttr incorrectly specified.");
                    return MS::kFailure;
                }
                jobArgs.userAttribs.insert(jobArgsArray[++i].asChar());
            }

            else if (arg == "-rt" || arg == "-root")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "root incorrectly specified.");
                    return MS::kFailure;
                }
                hasRoot = true;
                MString root = jobArgsArray[++i];

                MSelectionList sel;
                if (sel.add(root) != MS::kSuccess)
                {
                    MString warn = root;
                    warn += " could not be select, skipping.";
                    MGlobal::displayWarning(warn);
                    continue;
                }

                unsigned int numRoots = sel.length();
                for (unsigned int j = 0; j < numRoots; ++j)
                {
                    MDagPath path;
                    if (sel.getDagPath(j, path) != MS::kSuccess)
                    {
                        MString warn = path.fullPathName();
                        warn += " (part of ";
                        warn += root;
                        warn += " ) not a DAG Node, skipping.";
                        MGlobal::displayWarning(warn);
                        continue;
                    }
                    jobArgs.dagPaths.insert(path);
                }
            }
            else if (arg == "-ef" || arg == "-eulerfilter")
            {
                jobArgs.filterEulerRotations = true;
            }
            else if (arg == "-df" || arg == "-dataformat")
            {
                if (i+1 >= numJobArgs)
                {
                    MGlobal::displayError(
                        "dataFormat incorrectly specified.");
                    return MS::kFailure;
                }
                MString dataFormat = jobArgsArray[++i];
                dataFormat.toLowerCase();
                if (dataFormat == "hdf")
                {
                    asOgawa = false;
                }
                else if (dataFormat == "ogawa")
                {
                    asOgawa = true;
                }
            }
            else
            {
                MString warn = "Ignoring unsupported flag: ";
                warn += jobArgsArray[i];
                MGlobal::displayWarning(warn);
            }
        } //  for i

        if (fileName == "")
        {
            MString error = "-file not specified.";
            MGlobal::displayError(error);
            return MS::kFailure;
        }

        {
            MString fileRule, expandName;
            MString alembicFileRule = "alembicCache";
            MString alembicFilePath = "cache/alembic";

            MString queryFileRuleCmd;
            queryFileRuleCmd.format("workspace -q -fre \"^1s\"",
                alembicFileRule);

            MString queryFolderCmd;
            queryFolderCmd.format("workspace -en `workspace -q -fre \"^1s\"`",
                alembicFileRule);

            // query the file rule for alembic cache
            MGlobal::executeCommand(queryFileRuleCmd, fileRule);
            if (fileRule.length() > 0)
            {
                // we have alembic file rule, query the folder
                MGlobal::executeCommand(queryFolderCmd, expandName);
            }
            else
            {
                // alembic file rule does not exist, create it
                MString addFileRuleCmd;
                addFileRuleCmd.format("workspace -fr \"^1s\" \"^2s\"",
                    alembicFileRule, alembicFilePath);
                MGlobal::executeCommand(addFileRuleCmd);

                // save the workspace. maya may discard file rules on exit
                MGlobal::executeCommand("workspace -s");

                // query the folder
                MGlobal::executeCommand(queryFolderCmd, expandName);
            }

            // resolve the expanded file rule
            if (expandName.length() == 0)
            {
                expandName = alembicFilePath;
            }

            // get the path to the alembic file rule
            MFileObject directory;
            directory.setRawFullName(expandName);
            MString directoryName = directory.resolvedFullName();

            // make sure the cache folder exists
            if (!directory.exists())
            {
                // create the cache folder
                MString createFolderCmd;
                createFolderCmd.format("sysFile -md \"^1s\"", directoryName);
                MGlobal::executeCommand(createFolderCmd);
            }

            // resolve the relative path
            MFileObject absoluteFile;
            absoluteFile.setRawFullName(fileName.c_str());
#if MAYA_API_VERSION < 201300
            if (absoluteFile.resolvedFullName() !=
                absoluteFile.expandedFullName())
            {
#else
            if (!MFileObject::isAbsolutePath(fileName.c_str())) {
#endif
                // this is a relative path
                MString absoluteFileName = directoryName + "/" +
                    fileName.c_str();
                absoluteFile.setRawFullName(absoluteFileName);
                fileName = absoluteFile.resolvedFullName().asChar();
            }
            else
            {
                fileName = absoluteFile.resolvedFullName().asChar();
            }

            // check the path must exist before writing
            MFileObject absoluteFilePath;
            absoluteFilePath.setRawFullName(absoluteFile.path());
            if (!absoluteFilePath.exists()) {
                MString error;
                error.format("Path ^1s does not exist!", absoluteFilePath.resolvedFullName());
                MGlobal::displayError(error);
                return MS::kFailure;
            }
        }

        // if -frameRelativeSample argument is not specified for a frame range,
        // we are assuming a -frameRelativeSample 0.0
        for (std::vector<FrameRangeArgs>::iterator range =
            frameRanges.begin(); range != frameRanges.end(); ++range)
        {
            if (range->shutterSamples.empty())
                range->shutterSamples.insert(0.0);
        }

        if (jobArgs.prefixFilters.empty())
        {
            jobArgs.prefixFilters.push_back("ABC_");
        }

        // the list of frame ranges for sampling
        std::vector<FrameRangeArgs> sampleRanges;
        std::vector<FrameRangeArgs> preRollRanges;
        for (std::vector<FrameRangeArgs>::const_iterator range =
            frameRanges.begin(); range != frameRanges.end(); ++range)
        {
            if (range->preRoll)
                preRollRanges.push_back(*range);
            else
                sampleRanges.push_back(*range);
        }

        // the list of frames written into the abc file
        std::set<double> geoSamples;
        std::set<double> transSamples;
        for (std::vector<FrameRangeArgs>::const_iterator range =
            sampleRanges.begin(); range != sampleRanges.end(); ++range)
        {
            for (double frame = range->startTime;
                frame <= range->endTime;
                frame += range->strideTime)
            {
                for (std::set<double>::const_iterator shutter =
                    range->shutterSamples.begin();
                    shutter != range->shutterSamples.end(); ++shutter)
                {
                    double curFrame = *shutter + frame;
                    if (!sampleGeo)
                    {
                        double intFrame = (double)(int)(
                            curFrame >= 0 ? curFrame + .5 : curFrame - .5);

                        // only insert samples that are close to being an integer
                        if (fabs(curFrame - intFrame) < 1e-4)
                        {
                            geoSamples.insert(curFrame);
                        }
                    }
                    else
                    {
                        geoSamples.insert(curFrame);
                    }
                    transSamples.insert(curFrame);
                }
            }

            if (geoSamples.empty())
            {
                geoSamples.insert(range->startTime);
            }

            if (transSamples.empty())
            {
                transSamples.insert(range->startTime);
            }
        }

        bool isAcyclic = false;
        if (sampleRanges.empty())
        {
            // no frame ranges or all frame ranges are pre-roll ranges
            hasRange = false;
            geoSamples.insert(frameRanges.back().startTime);
            transSamples.insert(frameRanges.back().startTime);
        }
        else
        {
            // check if the time range is even (cyclic)
            // otherwise, we will use acyclic
            // sub frames pattern
            std::vector<double> pattern(
                sampleRanges.begin()->shutterSamples.begin(),
                sampleRanges.begin()->shutterSamples.end());
            std::transform(pattern.begin(), pattern.end(), pattern.begin(),
                std::bind2nd(std::plus<double>(),
                    sampleRanges.begin()->startTime));

            // check the frames against the pattern
            std::vector<double> timeSamples(
                transSamples.begin(), transSamples.end());
            for (size_t i = 0; i < timeSamples.size(); i++)
            {
                // next pattern
                if (i % pattern.size() == 0 && i / pattern.size() > 0)
                {
                    std::transform(pattern.begin(), pattern.end(),
                        pattern.begin(), std::bind2nd(std::plus<double>(),
                            sampleRanges.begin()->strideTime));
                }

                // pattern mismatch, we use acyclic time sampling type
                if (timeSamples[i] != pattern[i % pattern.size()])
                {
                    isAcyclic = true;
                    break;
                }
            }
        }

        // the list of frames to pre-roll
        std::set<double> preRollSamples;
        for (std::vector<FrameRangeArgs>::const_iterator range =
            preRollRanges.begin(); range != preRollRanges.end(); ++range)
        {
            for (double frame = range->startTime;
                frame <= range->endTime;
                frame += range->strideTime)
            {
                for (std::set<double>::const_iterator shutter =
                    range->shutterSamples.begin();
                    shutter != range->shutterSamples.end(); ++shutter)
                {
                    double curFrame = *shutter + frame;
                    preRollSamples.insert(curFrame);
                }
            }

            if (preRollSamples.empty())
            {
                preRollSamples.insert(range->startTime);
            }
        }

        if (jobArgs.dagPaths.size() > 1)
        {
            // check for validity of the DagPath relationships complexity : n^2

            util::ShapeSet::const_iterator m, n;
            util::ShapeSet::const_iterator end = jobArgs.dagPaths.end();
            for (m = jobArgs.dagPaths.begin(); m != end; )
            {
                MDagPath path1 = *m;
                m++;
                for (n = m; n != end; n++)
                {
                    MDagPath path2 = *n;
                    if (util::isAncestorDescendentRelationship(path1,path2))
                    {
                        MString errorMsg = path1.fullPathName();
                        errorMsg += " and ";
                        errorMsg += path2.fullPathName();
                        errorMsg += " have an ancestor relationship.";
                        MGlobal::displayError(errorMsg);
                        return MS::kFailure;
                    }
                }  // for n
            }  // for m
        }
        // no root is specified, and we aren't using a selection
        // so we'll try to translate the whole Maya scene by using all
        // children of the world as roots.
        else if (!hasRoot && !jobArgs.useSelectionList)
        {
            MSelectionList sel;
#if MAYA_API_VERSION >= 201100
            sel.add("|*", true);
#else
            // older versions of Maya will not be able to find top level nodes
            // within namespaces
            sel.add("|*");
#endif
            unsigned int numRoots = sel.length();
            for (unsigned int i = 0; i < numRoots; ++i)
            {
                MDagPath path;
                sel.getDagPath(i, path);
                jobArgs.dagPaths.insert(path);
            }
        }
        else if (hasRoot && jobArgs.dagPaths.empty())
        {
            MString errorMsg = "No valid root nodes were specified.";
            MGlobal::displayError(errorMsg);
            return MS::kFailure;
        }
        else if (jobArgs.useSelectionList)
        {
            MSelectionList activeList;
            MGlobal::getActiveSelectionList(activeList);
            if (activeList.length() == 0)
            {
                MString errorMsg =
                    "-selection specified but nothing is actively selected.";
                MGlobal::displayError(errorMsg);
                return MS::kFailure;
            }
        }

        AbcA::TimeSamplingPtr transTime, geoTime;

        if (hasRange)
        {
            if (isAcyclic)
            {
                // acyclic, uneven time sampling
                // e.g. [0.8, 1, 1.2], [2.8, 3, 3.2], .. not continuous
                //      [0.8, 1, 1.2], [1.7, 2, 2.3], .. shutter different
                std::vector<double> samples(
                    transSamples.begin(), transSamples.end());
                std::transform(samples.begin(), samples.end(), samples.begin(),
                    std::bind2nd(std::multiplies<double>(), util::spf()));
                transTime.reset(new AbcA::TimeSampling(AbcA::TimeSamplingType(
                    AbcA::TimeSamplingType::kAcyclic), samples));
            }
            else
            {
                // cyclic, even time sampling between time periods
                // e.g. [0.8, 1, 1.2], [1.8, 2, 2.2], ...
                std::vector<double> samples;
                double startTime = sampleRanges[0].startTime;
                double strideTime = sampleRanges[0].strideTime;
                for (std::set<double>::const_iterator shutter =
                    sampleRanges[0].shutterSamples.begin();
                    shutter != sampleRanges[0].shutterSamples.end();
                    ++shutter)
                {
                    samples.push_back((startTime + *shutter) * util::spf());
                }

                if (samples.size() > 1)
                {
                    Alembic::Util::uint32_t numSamples =
                        static_cast<Alembic::Util::uint32_t>(samples.size());
                    transTime.reset(
                        new AbcA::TimeSampling(AbcA::TimeSamplingType(
                            numSamples, strideTime * util::spf()), samples));
                }
                // uniform sampling
                else
                {
                    transTime.reset(new AbcA::TimeSampling(
                        strideTime * util::spf(), samples[0]));
                }
            }
        }
        else
        {
            // time ranges are not specified
            transTime.reset(new AbcA::TimeSampling());
        }

        if (sampleGeo || !hasRange)
        {
            geoTime = transTime;
        }
        else
        {
            // sampling geo on whole frames
            if (isAcyclic)
            {
                // acyclic, uneven time sampling
                std::vector<double> samples(
                    geoSamples.begin(), geoSamples.end());
                // one more sample for setup()
                if (*transSamples.begin() != *geoSamples.begin())
                    samples.insert(samples.begin(), *transSamples.begin());
                std::transform(samples.begin(), samples.end(), samples.begin(),
                    std::bind2nd(std::multiplies<double>(), util::spf()));
                geoTime.reset(new AbcA::TimeSampling(AbcA::TimeSamplingType(
                    AbcA::TimeSamplingType::kAcyclic), samples));
            }
            else
            {
                double geoStride = sampleRanges[0].strideTime;
                if (geoStride < 1.0)
                    geoStride = 1.0;

                double geoStart = *geoSamples.begin() * util::spf();
                geoTime.reset(new AbcA::TimeSampling(
                    geoStride * util::spf(), geoStart));
            }
        }

        AbcWriteJobPtr job(new AbcWriteJob(fileName.c_str(), asOgawa,
            transSamples, transTime, geoSamples, geoTime, jobArgs));

       jobList.push_front(job);

        // make sure we add additional whole frames, if we arent skipping
        // the inbetween ones
        if (!skipFrame && !allFrameRange.empty())
        {
            double localMin = *(transSamples.begin());
            std::set<double>::iterator last = transSamples.end();
            last--;
            double localMax = *last;

            double globalMin = *(allFrameRange.begin());
            last = allFrameRange.end();
            last--;
            double globalMax = *last;

            // if the min of our current frame range is beyond
            // what we know about, pad a few more frames
            if (localMin > globalMax)
            {
                for (double f = globalMax; f < localMin; f++)
                {
                    allFrameRange.insert(f);
                }
            }

            // if the max of our current frame range is beyond
            // what we know about, pad a few more frames
            if (localMax < globalMin)
            {
                for (double f = localMax; f < globalMin; f++)
                {
                    allFrameRange.insert(f);
                }
            }
        }

        // right now we just copy over the translation samples since
        // they are guaranteed to contain all the geometry samples
        allFrameRange.insert(transSamples.begin(), transSamples.end());

        // copy over the pre-roll samples
        allFrameRange.insert(preRollSamples.begin(), preRollSamples.end());
    }

    // add extra evaluation run up, if necessary
    if (startEvaluationTime != DBL_MAX && !allFrameRange.empty())
    {
        double firstFrame = *allFrameRange.begin();
        for (double f = startEvaluationTime; f < firstFrame; ++f)
        {
            allFrameRange.insert(f);
        }
    }

    std::set<double>::iterator it = allFrameRange.begin();
    std::set<double>::iterator itEnd = allFrameRange.end();

    MComputation computation;
    computation.beginComputation();

    // loop through every frame in the list, if a job has that frame in it's
    // list of transform or shape frames, then it will write out data and
    // call the perFrameCallback, if that frame is also the last one it has
    // to work on then it will also call the postCallback.
    // If it doesn't have this frame, then it does nothing
    for (; it != itEnd; it++)
    {
        if (verbose)
        {
            double frame = *it;
            MString info;
            info = frame;
            MGlobal::displayInfo(info);
        }

        MGlobal::viewFrame(*it);
        std::list< AbcWriteJobPtr >::iterator j = jobList.begin();
        std::list< AbcWriteJobPtr >::iterator jend = jobList.end();
        while (j != jend)
        {
            if (computation.isInterruptRequested())
                return MS::kFailure;

            bool lastFrame = (*j)->eval(*it);

            if (lastFrame)
            {
                j = jobList.erase(j);
            }
            else
                j++;
        }
    }
    computation.endComputation();

    // set the time back
    MGlobal::viewFrame(oldCurTime);

    return MS::kSuccess;
}
catch (Alembic::Util::Exception & e)
{
    MString theError("Alembic Exception encountered: ");
    theError += e.what();
    MGlobal::displayError(theError);
    return MS::kFailure;
}
catch (std::exception & e)
{
    MString theError("std::exception encountered: ");
    theError += e.what();
    MGlobal::displayError(theError);
    return MS::kFailure;
}

}
예제 #27
0
//
// Write out the "file" commands which specify the reference files used by
// the scene.
//
void maTranslator::writeReferences(fstream& f)
{
	MStringArray	files;

	MFileIO::getReferences(files);

	unsigned	numRefs = files.length();
	unsigned	i;

	for (i = 0; i < numRefs; i++)
	{
		MString	refCmd = "file -r";
		MString	fileName = files[i];
		MString	nsName = "";

		//
		// For simplicity, we assume that namespaces are always used when
		// referencing.
		//
		MString tempCmd = "file -q -ns \"";
		tempCmd += fileName + "\"";

		if (MGlobal::executeCommand(tempCmd, nsName))
		{
			refCmd += " -ns \"";
			refCmd += nsName + "\"";
		}
		else
			MGlobal::displayWarning("Could not get namespace name.");

		//
		// Is this a deferred reference?
		//
		tempCmd = "file -q -dr \"";
		tempCmd += fileName + "\"";

		int	isDeferred;

		if (MGlobal::executeCommand(tempCmd, isDeferred))
		{
			if (isDeferred) refCmd += " -dr 1";
		}
		else
			MGlobal::displayWarning("Could not get deferred reference info.");

		//
		// Get the file's reference node, if it has one.
		//
		tempCmd = "file -q -rfn \"";
		tempCmd += fileName + "\"";

		MString	refNode;

		if (MGlobal::executeCommand(tempCmd, refNode))
		{
			if (refNode.length() > 0)
			{
				refCmd += " -rfn \"";
				refCmd += refNode + "\"";
			}
		}
		else
			MGlobal::displayInfo("Could not query reference node name.");

		//
		// Write out the reference command.
		//
		f << refCmd.asChar() << " \"" << fileName.asChar() << "\";" << endl;
	}
}
/** Create a RIB compatible subdivision surface representation using a Maya polygon mesh.
 */
liqRibSubdivisionData::liqRibSubdivisionData( MObject mesh )
  : numFaces( 0 ),
    numPoints ( 0 ),
    nverts(),
    verts(),
    vertexParam( NULL ),
    interpolateBoundary( 0 ),
    uvDetail( rFaceVarying ),
    trueFacevarying( false )
{
	CM_TRACE_FUNC("liqRibSubdivisionData::liqRibSubdivisionData("<<MFnDagNode(mesh).fullPathName()<<")");

  LIQDEBUGPRINTF( "-> creating subdivision surface\n" );
  MFnMesh fnMesh( mesh );
  name = fnMesh.name();
  longName = fnMesh.fullPathName();

  checkExtraTags( mesh );

  numPoints = fnMesh.numVertices();

  // UV sets -----------------
  //
  const unsigned numSTs = fnMesh.numUVs();
  const unsigned numUVSets = fnMesh.numUVSets();
  MString currentUVSetName;
  MStringArray extraUVSetNames;
  fnMesh.getCurrentUVSetName( currentUVSetName );
  MStringArray UVSetNames;
  fnMesh.getUVSetNames( UVSetNames );

  for ( unsigned i( 0 ); i < numUVSets; i++ ) 
    if( UVSetNames[i] != currentUVSetName )
      extraUVSetNames.append( UVSetNames[i] );

  numFaces = fnMesh.numPolygons();
  const unsigned numFaceVertices( fnMesh.numFaceVertices() );
  unsigned face( 0 );
  unsigned faceVertex( 0 );
  unsigned count;
  unsigned vertex;
  float S;
  float T;
  MPoint point;
  liqTokenPointer pointsPointerPair;
  liqTokenPointer pFaceVertexSPointer;
  liqTokenPointer pFaceVertexTPointer;

  // Allocate memory and tokens
  nverts = shared_array< RtInt >( new RtInt[ numFaces ] );
  verts = shared_array< RtInt >( new RtInt[ numFaceVertices ] );

  pointsPointerPair.set( "P", rPoint, numPoints );
  pointsPointerPair.setDetailType( rVertex );

  std::vector<liqTokenPointer> UVSetsArray;
  UVSetsArray.reserve( 1 + extraUVSetNames.length() );

  if( numSTs > 0 ) 
  {
    liqTokenPointer pFaceVertexPointerPair;

    pFaceVertexPointerPair.set( "st", rFloat, numFaceVertices, 2 );
    pFaceVertexPointerPair.setDetailType( uvDetail );

    UVSetsArray.push_back( pFaceVertexPointerPair );

    for ( unsigned j( 0 ); j<extraUVSetNames.length(); j++) 
    {
      liqTokenPointer pFaceVertexPointerPair;

      pFaceVertexPointerPair.set( extraUVSetNames[j].asChar(), rFloat, numFaceVertices, 2 );
      pFaceVertexPointerPair.setDetailType( uvDetail );

      UVSetsArray.push_back( pFaceVertexPointerPair );
    }

    if( liqglo.liqglo_outputMeshUVs ) 
    {
      // Match MTOR, which also outputs face-varying STs as well for some reason - Paul
      // not anymore - Philippe
      pFaceVertexSPointer.set( "u", rFloat, numFaceVertices );
      pFaceVertexSPointer.setDetailType( uvDetail );

      pFaceVertexTPointer.set( "v", rFloat, numFaceVertices );
      pFaceVertexTPointer.setDetailType( uvDetail );
    }
  }

  vertexParam = pointsPointerPair.getTokenFloatArray();

  // Read the mesh from Maya
  for ( MItMeshPolygon polyIt ( mesh ); polyIt.isDone() == false; polyIt.next() ) 
  {
    count = polyIt.polygonVertexCount();
    nverts[face] = count;
    unsigned i = count;
    
    while( i )
    {
      --i;
      vertex = polyIt.vertexIndex( i );
      verts[faceVertex] = vertex;
      point = polyIt.point( i, MSpace::kObject );
      pointsPointerPair.setTokenFloat( vertex, point.x, point.y, point.z );

      if( UVSetsArray.size() ) 
      {
        fnMesh.getPolygonUV( face, i, S, T );

        UVSetsArray[0].setTokenFloat( faceVertex, 0, S );
        UVSetsArray[0].setTokenFloat( faceVertex, 1, 1 - T );

        for ( unsigned j( 1 ); j<=extraUVSetNames.length(); j++ ) 
        {
          fnMesh.getPolygonUV( face, i, S, T, &extraUVSetNames[j] );

          UVSetsArray[j].setTokenFloat( faceVertex, 0, S );
          UVSetsArray[j].setTokenFloat( faceVertex, 1, 1 - T );
        }

        if( liqglo.liqglo_outputMeshUVs ) 
        {
          // Match MTOR, which always outputs face-varying STs as well for some reason - Paul
          pFaceVertexSPointer.setTokenFloat( faceVertex, S );
          pFaceVertexTPointer.setTokenFloat( faceVertex, 1 - T );
        }
      }

      ++faceVertex;
    }

    ++face;
  }

  // Add tokens to array and clean up after
  tokenPointerArray.push_back( pointsPointerPair );

  if( UVSetsArray.size() ) 
    tokenPointerArray.insert( tokenPointerArray.end(), UVSetsArray.begin(), UVSetsArray.end() );
  

  if( liqglo.liqglo_outputMeshUVs ) 
  {
    assert( !pFaceVertexSPointer );
    tokenPointerArray.push_back( pFaceVertexSPointer );
    assert( !pFaceVertexTPointer );
    tokenPointerArray.push_back( pFaceVertexTPointer );
  }

  addAdditionalSurfaceParameters( mesh );
}
예제 #29
0
MStatus animExport::writer(	const MFileObject& file,
								const MString& options,
								FileAccessMode mode)
{
	MStatus status = MS::kFailure;

#ifdef MAYA_EVAL_VERSION
	status = MS::kFailure;
	return status;
#endif

	MString fileName = file.fullName();
#if defined (OSMac_)
	char fname[MAXPATHLEN];
	strcpy (fname, fileName.asChar());
	ofstream animFile(fname);
#else
	ofstream animFile(fileName.asChar());
#endif
	//	Defaults.
	//
	MString copyFlags("copyKey -cb api -fea 1 ");
	int precision = kDefaultPrecision;
	bool nodeNames = true;
	bool verboseUnits = false;

	//	Parse the options. The options syntax is in the form of
	//	"flag=val;flag1=val;flag2=val"
	//
	MString exportFlags;
	if (options.length() > 0) {
		const MString flagPrecision("precision");
		const MString flagNodeNames("nodeNames");
		const MString flagVerboseUnits("verboseUnits");
		const MString flagCopyKeyCmd("copyKeyCmd");

		//	Start parsing.
		//
		MStringArray optionList;
		MStringArray theOption;
		options.split(';', optionList);

		unsigned nOptions = optionList.length();
		for (unsigned i = 0; i < nOptions; i++) {
			theOption.clear();
			optionList[i].split('=', theOption);
			if (theOption.length() < 1) {
				continue;
			}

			if (theOption[0] == flagPrecision && theOption.length() > 1) {
				if (theOption[1].isInt()) {
					precision = theOption[1].asInt();
				}
			} else if (	theOption[0] == 
						flagNodeNames && theOption.length() > 1) {
				if (theOption[1].isInt()) {
					nodeNames = (theOption[1].asInt()) ? true : false;
				}
			}
			else if (theOption[0] == 
					flagVerboseUnits && theOption.length() > 1) {
				if (theOption[1].isInt()) {
					verboseUnits = (theOption[1].asInt()) ? true : false;
				}
			} else if (	theOption[0] == 
						flagCopyKeyCmd && theOption.length() > 1) {

				//	Replace any '>' characters with '"'. This is needed
				//	since the file translator option boxes do not handle
				//	escaped quotation marks.
				//
				const char *optStr = theOption[1].asChar();
				size_t nChars = strlen(optStr);
				char *copyStr = new char[nChars+1];

				copyStr = strcpy(copyStr, optStr);
				for (size_t j = 0; j < nChars; j++) {
					if (copyStr[j] == '>') {
						copyStr[j] = '"';
					}
				}
		
				copyFlags += copyStr;
				delete copyStr;
			}
		}
	}
	
	//	Set the precision of the ofstream.
	//
	animFile.precision(precision);

	status = exportSelected(animFile, copyFlags, nodeNames, verboseUnits);

	animFile.flush();
	animFile.close();

	return status;
}
예제 #30
0
static MStatus
convertToMayaMeshData(OpenSubdiv::Far::TopologyRefiner const & refiner,
    std::vector<Vertex> const & vertexBuffer, MFnMesh const & inMeshFn,
        MObject newMeshDataObj) {

    MStatus status;

    typedef OpenSubdiv::Far::ConstIndexArray IndexArray;

    int maxlevel = refiner.GetMaxLevel();

    OpenSubdiv::Far::TopologyLevel const & refLastLevel 
                                                = refiner.GetLevel(maxlevel);

    int nfaces = refLastLevel.GetNumFaces();
        
    // Init Maya Data

    // -- Face Counts
    MIntArray faceCounts(nfaces);
    for (int face=0; face < nfaces; ++face) {
        faceCounts[face] = 4;
    }

    // -- Face Connects
    MIntArray faceConnects(nfaces*4);
    for (int face=0, idx=0; face < nfaces; ++face) {
        IndexArray fverts = refLastLevel.GetFaceVertices(face);
        for (int vert=0; vert < fverts.size(); ++vert) {
            faceConnects[idx++] = fverts[vert];
        }
    }

    // -- Points
    MFloatPointArray points(refLastLevel.GetNumVertices());
    Vertex const * v = &vertexBuffer.at(0);

    for (int level=1; level<=maxlevel; ++level) {
        int nverts = refiner.GetLevel(level).GetNumVertices();
        if (level==maxlevel) {
            for (int vert=0; vert < nverts; ++vert, ++v) {
                points.set(vert, v->position[0], v->position[1], v->position[2]);
            }
        } else {
            v += nverts;
        }
    }

    // Create New Mesh from MFnMesh
    MFnMesh newMeshFn;
    MObject newMeshObj = newMeshFn.create(points.length(), faceCounts.length(),
        points, faceCounts, faceConnects, newMeshDataObj, &status);
    MCHECKERR(status, "Cannot create new mesh");

    int fvarTotalWidth = 0;

    if (fvarTotalWidth > 0) {

        // Get face-varying set names and other info from the inMesh
        MStringArray uvSetNames;
        MStringArray colorSetNames;
        std::vector<int> colorSetChannels;
        std::vector<MFnMesh::MColorRepresentation> colorSetReps;
        int totalColorSetChannels = 0;
        status = getMayaFvarFieldParams(inMeshFn, uvSetNames, colorSetNames,
            colorSetChannels, colorSetReps, totalColorSetChannels);

#if defined(DEBUG) or defined(_DEBUG)
        int numUVSets = uvSetNames.length();
        int expectedFvarTotalWidth = numUVSets*2 + totalColorSetChannels;
        assert(fvarTotalWidth == expectedFvarTotalWidth);
#endif

// XXXX fvar stuff here

    }

    return MS::kSuccess;
}