Esempio n. 1
0
/******************************************************************************
* Renders the geometry.
******************************************************************************/
void OpenGLArrowPrimitive::render(SceneRenderer* renderer)
{
	OVITO_REPORT_OPENGL_ERRORS();
	OVITO_ASSERT(_contextGroup == QOpenGLContextGroup::currentContextGroup());
	OVITO_ASSERT(_elementCount >= 0);
	OVITO_ASSERT(_mappedChunkIndex == -1);

	ViewportSceneRenderer* vpRenderer = dynamic_object_cast<ViewportSceneRenderer>(renderer);

	if(_elementCount <= 0 || !vpRenderer)
		return;

	vpRenderer->rebindVAO();

	if(shadingMode() == NormalShading) {
		if(renderingQuality() == HighQuality && shape() == CylinderShape)
			renderWithElementInfo(vpRenderer);
		else
			renderWithNormals(vpRenderer);
	}
	else if(shadingMode() == FlatShading) {
		renderWithElementInfo(vpRenderer);
	}
	OVITO_REPORT_OPENGL_ERRORS();
}
Esempio n. 2
0
/******************************************************************************
* Renders the geometry as with extra information passed to the vertex shader.
******************************************************************************/
void OpenGLArrowPrimitive::renderWithElementInfo(ViewportSceneRenderer* renderer)
{
	QOpenGLShaderProgram* shader = renderer->isPicking() ? _pickingShader : _shader;
	if(!shader)
		return;
	if(!shader->bind())
		throw Exception(QStringLiteral("Failed to bind OpenGL shader."));

	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);

	shader->setUniformValue("modelview_matrix",
			(QMatrix4x4)renderer->modelViewTM());
	shader->setUniformValue("modelview_uniform_scale", (float)pow(std::abs(renderer->modelViewTM().determinant()), (FloatType(1.0/3.0))));
	shader->setUniformValue("modelview_projection_matrix",
			(QMatrix4x4)(renderer->projParams().projectionMatrix * renderer->modelViewTM()));
	shader->setUniformValue("projection_matrix", (QMatrix4x4)renderer->projParams().projectionMatrix);
	shader->setUniformValue("inverse_projection_matrix", (QMatrix4x4)renderer->projParams().inverseProjectionMatrix);
	shader->setUniformValue("is_perspective", renderer->projParams().isPerspective);

	AffineTransformation viewModelTM = renderer->modelViewTM().inverse();
	Vector3 eye_pos = viewModelTM.translation();
	shader->setUniformValue("eye_pos", eye_pos.x(), eye_pos.y(), eye_pos.z());
	Vector3 viewDir = viewModelTM * Vector3(0,0,1);
	shader->setUniformValue("parallel_view_dir", viewDir.x(), viewDir.y(), viewDir.z());

	GLint viewportCoords[4];
	glGetIntegerv(GL_VIEWPORT, viewportCoords);
	shader->setUniformValue("viewport_origin", (float)viewportCoords[0], (float)viewportCoords[1]);
	shader->setUniformValue("inverse_viewport_size", 2.0f / (float)viewportCoords[2], 2.0f / (float)viewportCoords[3]);

	GLint pickingBaseID;
	if(renderer->isPicking()) {
		pickingBaseID = renderer->registerSubObjectIDs(elementCount());
		renderer->activateVertexIDs(shader, _chunkSize * _verticesPerElement, true);
		OVITO_CHECK_OPENGL(shader->setUniformValue("verticesPerElement", (GLint)_verticesPerElement));
	}

	for(int chunkIndex = 0; chunkIndex < _verticesWithElementInfo.size(); chunkIndex++, pickingBaseID += _chunkSize) {
		int chunkStart = chunkIndex * _chunkSize;
		int chunkSize = std::min(_elementCount - chunkStart, _chunkSize);

		if(renderer->isPicking())
			shader->setUniformValue("pickingBaseID", pickingBaseID);

		_verticesWithElementInfo[chunkIndex].bindPositions(renderer, shader, offsetof(VertexWithElementInfo, pos));
		_verticesWithElementInfo[chunkIndex].bind(renderer, shader, "cylinder_base", GL_FLOAT, offsetof(VertexWithElementInfo, base), 3, sizeof(VertexWithElementInfo));
		_verticesWithElementInfo[chunkIndex].bind(renderer, shader, "cylinder_axis", GL_FLOAT, offsetof(VertexWithElementInfo, dir), 3, sizeof(VertexWithElementInfo));
		_verticesWithElementInfo[chunkIndex].bind(renderer, shader, "cylinder_radius", GL_FLOAT, offsetof(VertexWithElementInfo, radius), 1, sizeof(VertexWithElementInfo));
		if(!renderer->isPicking())
			_verticesWithElementInfo[chunkIndex].bindColors(renderer, shader, 4, offsetof(VertexWithElementInfo, color));

		if(_usingGeometryShader && (shadingMode() == FlatShading || renderingQuality() == HighQuality)) {
			OVITO_CHECK_OPENGL(glDrawArrays(GL_POINTS, 0, chunkSize));
		}
		else {
			int stripPrimitivesPerElement = _stripPrimitiveVertexCounts.size() / _chunkSize;
			OVITO_CHECK_OPENGL(renderer->glMultiDrawArrays(GL_TRIANGLE_STRIP, _stripPrimitiveVertexStarts.data(), _stripPrimitiveVertexCounts.data(), stripPrimitivesPerElement * chunkSize));

			int fanPrimitivesPerElement = _fanPrimitiveVertexCounts.size() / _chunkSize;
			OVITO_CHECK_OPENGL(renderer->glMultiDrawArrays(GL_TRIANGLE_FAN, _fanPrimitiveVertexStarts.data(), _fanPrimitiveVertexCounts.data(), fanPrimitivesPerElement * chunkSize));
		}

		_verticesWithElementInfo[chunkIndex].detachPositions(renderer, shader);
		_verticesWithElementInfo[chunkIndex].detach(renderer, shader, "cylinder_base");
		_verticesWithElementInfo[chunkIndex].detach(renderer, shader, "cylinder_axis");
		_verticesWithElementInfo[chunkIndex].detach(renderer, shader, "cylinder_radius");
		if(!renderer->isPicking())
			_verticesWithElementInfo[chunkIndex].detachColors(renderer, shader);
	}
	shader->enableAttributeArray("cylinder_base");
	shader->enableAttributeArray("cylinder_axis");
	shader->enableAttributeArray("cylinder_radius");

	if(renderer->isPicking())
		renderer->deactivateVertexIDs(shader, true);

	shader->release();
}
Esempio n. 3
0
/******************************************************************************
* Creates the geometry for a single arrow element.
******************************************************************************/
void OpenGLArrowPrimitive::createArrowElement(int index, const Point3& pos, const Vector3& dir, const ColorA& color, FloatType width)
{
	const float arrowHeadRadius = width * 2.5f;
	const float arrowHeadLength = arrowHeadRadius * 1.8f;

	if(shadingMode() == NormalShading) {

		// Build local coordinate system.
		Vector_3<float> t, u, v;
		float length = dir.length();
		if(length != 0) {
			t = dir / length;
			if(dir.y() != 0 || dir.x() != 0)
				u = Vector_3<float>(dir.y(), -dir.x(), 0);
			else
				u = Vector_3<float>(-dir.z(), 0, dir.x());
			u.normalize();
			v = u.cross(t);
		}
		else {
			t.setZero();
			u.setZero();
			v.setZero();
		}

		ColorAT<float> c = color;
		Point_3<float> v1 = pos;
		Point_3<float> v2;
		Point_3<float> v3 = v1 + dir;
		float r;
		if(length > arrowHeadLength) {
			v2 = v1 + t * (length - arrowHeadLength);
			r = arrowHeadRadius;
		}
		else {
			v2 = v1;
			r = arrowHeadRadius * length / arrowHeadLength;
		}

		OVITO_ASSERT(_mappedVerticesWithNormals);
		VertexWithNormal* vertex = _mappedVerticesWithNormals + (index * _verticesPerElement);

		// Generate vertices for cylinder.
		for(int i = 0; i <= _cylinderSegments; i++) {
			Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
			Vector_3<float> d = n * width;
			vertex->pos = v1 + d;
			vertex->normal = n;
			vertex->color = c;
			vertex++;
			vertex->pos = v2 + d;
			vertex->normal = n;
			vertex->color = c;
			vertex++;
		}

		// Generate vertices for head cone.
		for(int i = 0; i <= _cylinderSegments; i++) {
			Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
			Vector_3<float> d = n * r;
			vertex->pos = v2 + d;
			vertex->normal = n;
			vertex->color = c;
			vertex++;
			vertex->pos = v3;
			vertex->normal = n;
			vertex->color = c;
			vertex++;
		}

		// Generate vertices for cylinder cap.
		for(int i = 0; i < _cylinderSegments; i++) {
			Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
			Vector_3<float> d = n * width;
			vertex->pos = v1 + d;
			vertex->normal = Vector_3<float>(0,0,-1);
			vertex->color = c;
			vertex++;
		}

		// Generate vertices for cone cap.
		for(int i = 0; i < _cylinderSegments; i++) {
			Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
			Vector_3<float> d = n * r;
			vertex->pos = v2 + d;
			vertex->normal = Vector_3<float>(0,0,-1);
			vertex->color = c;
			vertex++;
		}
	}
	else if(shadingMode() == FlatShading) {

		Vector_3<float> t;
		float length = dir.length();
		if(length != 0)
			t = dir / length;
		else
			t.setZero();

		ColorAT<float> c = color;
		Point_3<float> base = pos;

		OVITO_ASSERT(_mappedVerticesWithElementInfo);
		VertexWithElementInfo* vertices = _mappedVerticesWithElementInfo + (index * _verticesPerElement);

		if(length > arrowHeadLength) {
			vertices[0].pos = Point_3<float>(length, 0, 0);
			vertices[1].pos = Point_3<float>(length - arrowHeadLength, arrowHeadRadius, 0);
			vertices[2].pos = Point_3<float>(length - arrowHeadLength, width, 0);
			vertices[3].pos = Point_3<float>(0, width, 0);
			vertices[4].pos = Point_3<float>(0, -width, 0);
			vertices[5].pos = Point_3<float>(length - arrowHeadLength, -width, 0);
			vertices[6].pos = Point_3<float>(length - arrowHeadLength, -arrowHeadRadius, 0);
		}
		else {
			float r = arrowHeadRadius * length / arrowHeadLength;
			vertices[0].pos = Point_3<float>(length, 0, 0);
			vertices[1].pos = Point_3<float>(0, r, 0);
			vertices[2].pos = Point_3<float>::Origin();
			vertices[3].pos = Point_3<float>::Origin();
			vertices[4].pos = Point_3<float>::Origin();
			vertices[5].pos = Point_3<float>::Origin();
			vertices[6].pos = Point_3<float>(0, -r, 0);
		}
		for(int i = 0; i < _verticesPerElement; i++, ++vertices) {
			vertices->base = base;
			vertices->dir = t;
			vertices->color = c;
		}
	}
}
Esempio n. 4
0
/******************************************************************************
* Allocates a particle buffer with the given number of elements.
******************************************************************************/
void OpenGLArrowPrimitive::startSetElements(int elementCount)
{
	OVITO_ASSERT(elementCount >= 0);
	OVITO_ASSERT(QOpenGLContextGroup::currentContextGroup() == _contextGroup);
	OVITO_ASSERT(_mappedChunkIndex == -1);
	_verticesWithNormals.clear();
	_verticesWithElementInfo.clear();

	_elementCount = elementCount;
	bool renderMesh = true;
	int stripsPerElement;
	int fansPerElement;
	int verticesPerStrip;
	int verticesPerFan;
	if(shadingMode() == NormalShading) {
		verticesPerStrip = _cylinderSegments * 2 + 2;
		verticesPerFan = _cylinderSegments;
		if(shape() == ArrowShape) {
			stripsPerElement = 2;
			fansPerElement = 2;
		}
		else {
			stripsPerElement = 1;
			fansPerElement = 2;
			if(renderingQuality() == HighQuality) {
				if(_usingGeometryShader) {
					verticesPerStrip = 1;
					stripsPerElement = 1;
				}
				else {
					verticesPerStrip = 14;
				}
				fansPerElement = verticesPerFan = 0;
				renderMesh = false;
			}
		}
	}
	else if(shadingMode() == FlatShading) {
		fansPerElement = 1;
		stripsPerElement = 0;
		verticesPerStrip = 0;
		if(shape() == ArrowShape)
			verticesPerFan = 7;
		else
			verticesPerFan = 4;
		if(_usingGeometryShader && shape() == CylinderShape) {
			verticesPerFan = 1;
		}
		renderMesh = false;
	}
	else OVITO_ASSERT(false);

	// Determine the VBO chunk size.
	_verticesPerElement = stripsPerElement * verticesPerStrip + fansPerElement * verticesPerFan;
	int bytesPerVertex = renderMesh ? sizeof(VertexWithNormal) : sizeof(VertexWithElementInfo);
	_chunkSize = std::min(_maxVBOSize / _verticesPerElement / bytesPerVertex, _elementCount);

	// Allocate VBOs.
	for(int i = _elementCount; i > 0; i -= _chunkSize) {
		if(renderMesh) {
			OpenGLBuffer<VertexWithNormal> buffer;
			buffer.create(QOpenGLBuffer::StaticDraw, std::min(i, _chunkSize), _verticesPerElement);
			_verticesWithNormals.push_back(buffer);
		}
		else {
			OpenGLBuffer<VertexWithElementInfo> buffer;
			buffer.create(QOpenGLBuffer::StaticDraw, std::min(i, _chunkSize), _verticesPerElement);
			_verticesWithElementInfo.push_back(buffer);
		}
	}
	OVITO_REPORT_OPENGL_ERRORS();

	// Prepare arrays to be passed to the glMultiDrawArrays() function.
	_stripPrimitiveVertexStarts.resize(_chunkSize * stripsPerElement);
	_stripPrimitiveVertexCounts.resize(_chunkSize * stripsPerElement);
	_fanPrimitiveVertexStarts.resize(_chunkSize * fansPerElement);
	_fanPrimitiveVertexCounts.resize(_chunkSize * fansPerElement);
	std::fill(_stripPrimitiveVertexCounts.begin(), _stripPrimitiveVertexCounts.end(), verticesPerStrip);
	std::fill(_fanPrimitiveVertexCounts.begin(), _fanPrimitiveVertexCounts.end(), verticesPerFan);
	auto ps_strip = _stripPrimitiveVertexStarts.begin();
	auto ps_fan = _fanPrimitiveVertexStarts.begin();
	for(GLint index = 0, baseIndex = 0; index < _chunkSize; index++) {
		for(int p = 0; p < stripsPerElement; p++, baseIndex += verticesPerStrip)
			*ps_strip++ = baseIndex;
		for(int p = 0; p < fansPerElement; p++, baseIndex += verticesPerFan)
			*ps_fan++ = baseIndex;
	}

	// Precompute cos() and sin() functions.
	if(shadingMode() == NormalShading) {
		_cosTable.resize(_cylinderSegments+1);
		_sinTable.resize(_cylinderSegments+1);
		for(int i = 0; i <= _cylinderSegments; i++) {
			float angle = (FLOATTYPE_PI * 2 / _cylinderSegments) * i;
			_cosTable[i] = std::cos(angle);
			_sinTable[i] = std::sin(angle);
		}
	}
}
Esempio n. 5
0
/******************************************************************************
* Creates the geometry for a single cylinder element.
******************************************************************************/
void OpenGLArrowPrimitive::createCylinderElement(int index, const Point3& pos, const Vector3& dir, const ColorA& color, FloatType width)
{
	if(_usingGeometryShader && (shadingMode() == FlatShading || renderingQuality() == HighQuality)) {
		OVITO_ASSERT(_mappedVerticesWithElementInfo);
		OVITO_ASSERT(_verticesPerElement == 1);
		VertexWithElementInfo* vertex = _mappedVerticesWithElementInfo + index;
		vertex->pos = vertex->base = pos;
		vertex->dir = dir;
		vertex->color = color;
		vertex->radius = width;
		return;
	}

	if(shadingMode() == NormalShading) {

		// Build local coordinate system.
		Vector_3<float> t, u, v;
		float length = dir.length();
		if(length != 0) {
			t = dir / length;
			if(dir.y() != 0 || dir.x() != 0)
				u = Vector_3<float>(dir.y(), -dir.x(), 0);
			else
				u = Vector_3<float>(-dir.z(), 0, dir.x());
			u.normalize();
			v = u.cross(t);
		}
		else {
			t.setZero();
			u.setZero();
			v.setZero();
		}

		ColorAT<float> c = color;
		Point_3<float> v1 = pos;
		Point_3<float> v2 = v1 + dir;

		if(renderingQuality() != HighQuality) {
			OVITO_ASSERT(_mappedVerticesWithNormals);
			VertexWithNormal* vertex = _mappedVerticesWithNormals + (index * _verticesPerElement);

			// Generate vertices for cylinder mantle.
			for(int i = 0; i <= _cylinderSegments; i++) {
				Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
				Vector_3<float> d = n * width;
				vertex->pos = v1 + d;
				vertex->normal = n;
				vertex->color = c;
				vertex++;
				vertex->pos = v2 + d;
				vertex->normal = n;
				vertex->color = c;
				vertex++;
			}

			// Generate vertices for first cylinder cap.
			for(int i = 0; i < _cylinderSegments; i++) {
				Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
				Vector_3<float> d = n * width;
				vertex->pos = v1 + d;
				vertex->normal = Vector_3<float>(0,0,-1);
				vertex->color = c;
				vertex++;
			}

			// Generate vertices for second cylinder cap.
			for(int i = _cylinderSegments - 1; i >= 0; i--) {
				Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v;
				Vector_3<float> d = n * width;
				vertex->pos = v2 + d;
				vertex->normal = Vector_3<float>(0,0,1);
				vertex->color = c;
				vertex++;
			}
		}
		else {
			// Create bounding box geometry around cylinder for raytracing.
			OVITO_ASSERT(_mappedVerticesWithElementInfo);
			VertexWithElementInfo* vertex = _mappedVerticesWithElementInfo + (index * _verticesPerElement);
			OVITO_ASSERT(_verticesPerElement == 14);
			u *= width;
			v *= width;
			Point3 corners[8] = {
					v1 - u - v,
					v1 - u + v,
					v1 + u - v,
					v1 + u + v,
					v2 - u - v,
					v2 - u + v,
					v2 + u + v,
					v2 + u - v
			};
			const static size_t stripIndices[14] = { 3,2,6,7,4,2,0,3,1,6,5,4,1,0 };
			for(int i = 0; i < 14; i++, vertex++) {
				vertex->pos = corners[stripIndices[i]];
				vertex->base = v1;
				vertex->dir = dir;
				vertex->color = c;
				vertex->radius = width;
			}
		}
	}
	else if(shadingMode() == FlatShading) {

		Vector_3<float> t;
		float length = dir.length();
		if(length != 0)
			t = dir / length;
		else
			t.setZero();

		ColorAT<float> c = color;
		Point_3<float> base = pos;

		OVITO_ASSERT(_mappedVerticesWithElementInfo);
		VertexWithElementInfo* vertices = _mappedVerticesWithElementInfo + (index * _verticesPerElement);
		vertices[0].pos = Point_3<float>(0, width, 0);
		vertices[1].pos = Point_3<float>(0, -width, 0);
		vertices[2].pos = Point_3<float>(length, -width, 0);
		vertices[3].pos = Point_3<float>(length, width, 0);
		for(int i = 0; i < _verticesPerElement; i++, ++vertices) {
			vertices->base = base;
			vertices->dir = t;
			vertices->color = c;
		}
	}
}
Esempio n. 6
0
MStatus
usdTranslatorExport::writer(const MFileObject &file, 
                 const MString &optionsString,
                 MPxFileTranslator::FileAccessMode mode ) {

    std::string fileName(file.fullName().asChar());
    JobExportArgs jobArgs;
    double startTime=1, endTime=1;
    bool append=false;
    
    // Get the options 
    if ( optionsString.length() > 0 ) {
        MStringArray optionList;
        MStringArray theOption;
        optionsString.split(';', optionList);
        for(int i=0; i<(int)optionList.length(); ++i) {
            theOption.clear();
            optionList[i].split('=', theOption);            
            if (theOption[0] == MString("exportReferencesAsInstanceable")) {
                jobArgs.exportRefsAsInstanceable = theOption[1].asInt();
            }
            if (theOption[0] == MString("shadingMode")) {
                // Set default (most common) options
                jobArgs.exportDisplayColor = true;
                jobArgs.shadingMode = PxrUsdMayaShadingModeTokens->none;
                
                if (theOption[1]=="None") {
                    jobArgs.exportDisplayColor = false;
                }else if (theOption[1]=="Look Colors") {
                    jobArgs.shadingMode = PxrUsdMayaShadingModeTokens->displayColor;
                } else if (theOption[1]=="RfM Shaders") {
                    TfToken shadingMode("pxrRis");
                    if (PxrUsdMayaShadingModeRegistry::GetInstance().GetExporter(shadingMode)) {
                        jobArgs.shadingMode = shadingMode;
                    }
                }
            }
            if (theOption[0] == MString("exportUVs")) {
                jobArgs.exportMeshUVs = theOption[1].asInt();
                jobArgs.exportNurbsExplicitUV = theOption[1].asInt();
            }
            if (theOption[0] == MString("normalizeUVs")) {
                jobArgs.normalizeMeshUVs = theOption[1].asInt();
                jobArgs.nurbsExplicitUVType = PxUsdExportJobArgsTokens->Uniform;
            }
            if (theOption[0] == MString("exportColorSets")) {
                jobArgs.exportColorSets = theOption[1].asInt();
            }
            if (theOption[0] == MString("renderableOnly")) {
                jobArgs.excludeInvisible = theOption[1].asInt();
            }
            if (theOption[0] == MString("allCameras")) {
                jobArgs.exportDefaultCameras = theOption[1].asInt();
            }
            if (theOption[0] == MString("renderLayerMode")) {
                jobArgs.renderLayerMode = PxUsdExportJobArgsTokens->defaultLayer;

                if (theOption[1]=="Use Current Layer") {
                    jobArgs.renderLayerMode = PxUsdExportJobArgsTokens->currentLayer;
                } else if (theOption[1]=="Modeling Variant Per Layer") {
                    jobArgs.renderLayerMode = PxUsdExportJobArgsTokens->modelingVariant;
                }
            }
            if (theOption[0] == MString("mergeXForm")) {
                jobArgs.mergeTransformAndShape = theOption[1].asInt();
            }
            if (theOption[0] == MString("defaultMeshScheme")) {            
                if (theOption[1]=="Polygonal Mesh") {
                    jobArgs.defaultMeshScheme = UsdGeomTokens->none;
                } else if (theOption[1]=="Bilinear SubDiv") {
                    jobArgs.defaultMeshScheme = UsdGeomTokens->bilinear;
                } else if (theOption[1]=="CatmullClark SDiv") {
                    jobArgs.defaultMeshScheme = UsdGeomTokens->catmullClark;
                } else if (theOption[1]=="Loop SDiv") {
                    jobArgs.defaultMeshScheme = UsdGeomTokens->loop;
                }
            }
            if (theOption[0] == MString("exportVisibility")) {
                jobArgs.exportVisibility = theOption[1].asInt();
            }
            if (theOption[0] == MString("animation")) {
                jobArgs.exportAnimation = theOption[1].asInt();
            }
            if (theOption[0] == MString("startTime")) {
                startTime = theOption[1].asDouble();
            }
            if (theOption[0] == MString("endTime")) {
                endTime = theOption[1].asDouble();
            }
        }
        // Now resync start and end frame based on animation mode
        if (jobArgs.exportAnimation) {
            if (endTime<startTime) endTime=startTime;
        } else {
            startTime=MAnimControl::currentTime().value();
            endTime=startTime;
        }
    }

    MSelectionList objSelList;
    if(mode == MPxFileTranslator::kExportActiveAccessMode) {
        // Get selected objects
        MGlobal::getActiveSelectionList(objSelList);
    } else if(mode == MPxFileTranslator::kExportAccessMode) {
        // Get all objects at DAG root
        objSelList.add("|*", true);
    }

    // Convert selection list to jobArgs dagPaths
    for (unsigned int i=0; i < objSelList.length(); i++) {
        MDagPath dagPath;
        if (objSelList.getDagPath(i, dagPath) == MS::kSuccess) {
            jobArgs.dagPaths.insert(dagPath);
        }
    }
    
    if (jobArgs.dagPaths.size()) {
        MTime oldCurTime = MAnimControl::currentTime();
        usdWriteJob writeJob(jobArgs);
        if (writeJob.beginJob(fileName, append, startTime, endTime)) {
            for (double i=startTime;i<(endTime+1);i++) {
                MGlobal::viewFrame(i);
                writeJob.evalJob(i);
            }
            writeJob.endJob();
            MGlobal::viewFrame(oldCurTime);
        }
    } else {
        MGlobal::displayWarning("No DAG nodes to export. Skipping");
    }
    
    return MS::kSuccess;
}
Esempio n. 7
0
MStatus usdImport::doIt(const MArgList & args)
{

    MStatus status;

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

    // Check that all flags were valid
    if (status != MS::kSuccess) {
        MGlobal::displayError("Invalid parameters detected.  Exiting.");
        return status;
    }

    JobImportArgs jobArgs;
    //bool verbose = argData.isFlagSet("verbose");
    
    std::string mFileName;
    if (argData.isFlagSet("file"))
    {
        // Get the value
        MString tmpVal;
        argData.getFlagArgument("file", 0, tmpVal);

        // resolve the path into an absolute path
        MFileObject absoluteFile;
        absoluteFile.setRawFullName(tmpVal);
        absoluteFile.setRawFullName( absoluteFile.resolvedFullName() ); // Make sure an absolute path

        if (!absoluteFile.exists()) {
            MGlobal::displayError("File does not exist.  Exiting.");
            return MS::kFailure;
        }

        // Set the fileName
        mFileName = absoluteFile.resolvedFullName().asChar();
        MGlobal::displayInfo(MString("Importing ") + MString(mFileName.c_str()));
    }
    
    if (mFileName.empty()) {
        MString error = "Non empty file specified. Skipping...";
        MGlobal::displayError(error);
        return MS::kFailure;
    }

    if (argData.isFlagSet("shadingMode")) {
        MString stringVal;
        argData.getFlagArgument("shadingMode", 0, stringVal);
        TfToken shadingMode(stringVal.asChar());

        if (shadingMode.IsEmpty()) {
            jobArgs.shadingMode = PxrUsdMayaShadingModeTokens->displayColor;
        }
        else {
            if (PxrUsdMayaShadingModeRegistry::GetInstance().GetExporter(shadingMode)) {
                jobArgs.shadingMode = shadingMode;
            }
            else {
                MGlobal::displayError(TfStringPrintf("No shadingMode '%s' found.  Setting shadingMode='none'", 
                            shadingMode.GetText()).c_str());
                jobArgs.shadingMode = PxrUsdMayaShadingModeTokens->none;
            }
        }
    }

    if (argData.isFlagSet("readAnimData"))
    {   
        bool tmpBool = false;
        argData.getFlagArgument("readAnimData", 0, tmpBool);
        jobArgs.readAnimData = tmpBool;
    }

    // Specify usd PrimPath.  Default will be "/<useFileBasename>"
    std::string mPrimPath;
    if (argData.isFlagSet("primPath"))
    {
        // Get the value
        MString tmpVal;
        argData.getFlagArgument("primPath", 0, tmpVal);
        mPrimPath = tmpVal.asChar();
    }

    // Add variant (variantSet, variant).  Multi-use
    std::map<std::string,std::string> mVariants;
    for (unsigned int i=0; i < argData.numberOfFlagUses("variant"); ++i)
    {
        MArgList tmpArgList;
        status = argData.getFlagArgumentList("variant", i, tmpArgList);
        // Get the value
        MString tmpKey = tmpArgList.asString(0, &status);
        MString tmpVal = tmpArgList.asString(1, &status);
        mVariants.insert( std::pair<std::string, std::string>(tmpKey.asChar(), tmpVal.asChar()) );
    }

    if (argData.isFlagSet("assemblyRep"))
    {
        // Get the value
        MString stringVal;
        argData.getFlagArgument("assemblyRep", 0, stringVal);
        std::string assemblyRep = stringVal.asChar();
        if (not assemblyRep.empty()) {
            jobArgs.assemblyRep = TfToken(assemblyRep);
        }
    }

    // Create the command
    if (mUsdReadJob) {
        delete mUsdReadJob;
    }


    // pass in assemblyTypeName and proxyShapeTypeName
    mUsdReadJob = new usdReadJob(mFileName, mPrimPath, mVariants, jobArgs,
            _assemblyTypeName, _proxyShapeTypeName);


    // Add optional command params
    if (argData.isFlagSet("parent"))
    {
        // Get the value
        MString tmpVal;
        argData.getFlagArgument("parent", 0, tmpVal);

        if (tmpVal.length()) {
            MSelectionList selList;
            selList.add(tmpVal);
            MDagPath dagPath;
            status = selList.getDagPath(0, dagPath);
            if (status != MS::kSuccess) {
                std::string errorStr = TfStringPrintf(
                        "Invalid path \"%s\"for -parent.",
                        tmpVal.asChar());
                MGlobal::displayError(MString(errorStr.c_str()));
                return MS::kFailure;
            }
            mUsdReadJob->setMayaRootDagPath( dagPath );
        }
    }

    // Execute the command
    std::vector<MDagPath> addedDagPaths;
    bool success = mUsdReadJob->doIt(&addedDagPaths);
    if (success) {
        TF_FOR_ALL(iter, addedDagPaths) {
            appendToResult(iter->fullPathName());
        }
    }
/******************************************************************************
* Lets the display object render the data object.
******************************************************************************/
void ParticleDisplay::render(TimePoint time, DataObject* dataObject, const PipelineFlowState& flowState, SceneRenderer* renderer, ObjectNode* contextNode)
{
	// Get input data.
	ParticlePropertyObject* positionProperty = dynamic_object_cast<ParticlePropertyObject>(dataObject);
	ParticlePropertyObject* radiusProperty = ParticlePropertyObject::findInState(flowState, ParticleProperty::RadiusProperty);
	ParticlePropertyObject* colorProperty = ParticlePropertyObject::findInState(flowState, ParticleProperty::ColorProperty);
	ParticleTypeProperty* typeProperty = dynamic_object_cast<ParticleTypeProperty>(ParticlePropertyObject::findInState(flowState, ParticleProperty::ParticleTypeProperty));
	ParticlePropertyObject* selectionProperty = renderer->isInteractive() ? ParticlePropertyObject::findInState(flowState, ParticleProperty::SelectionProperty) : nullptr;
	ParticlePropertyObject* transparencyProperty = ParticlePropertyObject::findInState(flowState, ParticleProperty::TransparencyProperty);
	ParticlePropertyObject* shapeProperty = ParticlePropertyObject::findInState(flowState, ParticleProperty::AsphericalShapeProperty);
	if(shadingMode() != ParticlePrimitive::NormalShading)
		shapeProperty = nullptr;

	// Get number of particles.
	int particleCount = positionProperty ? (int)positionProperty->size() : 0;

	// Do we have to re-create the geometry buffer from scratch?
	bool recreateBuffer = !_particleBuffer || !_particleBuffer->isValid(renderer);

	// If rendering quality is set to automatic, pick quality level based on number of particles.
	ParticlePrimitive::RenderingQuality renderQuality = effectiveRenderingQuality(renderer, positionProperty);

	// Determine effective particle shape.
	ParticlePrimitive::ParticleShape effectiveParticleShape = particleShape();
	if(effectiveParticleShape == ParticlePrimitive::SquareShape && shapeProperty != nullptr)
		effectiveParticleShape = ParticlePrimitive::BoxShape;
	else
		shapeProperty = nullptr;

	// Set shading mode and rendering quality.
	if(!recreateBuffer) {
		recreateBuffer |= !(_particleBuffer->setShadingMode(shadingMode()));
		recreateBuffer |= !(_particleBuffer->setRenderingQuality(renderQuality));
		recreateBuffer |= !(_particleBuffer->setParticleShape(effectiveParticleShape));
		recreateBuffer |= ((transparencyProperty != nullptr) != _particleBuffer->translucentParticles());
	}

	// Do we have to resize the render buffer?
	bool resizeBuffer = recreateBuffer || (_particleBuffer->particleCount() != particleCount);

	// Do we have to update the particle positions in the render buffer?
	bool updatePositions = _positionsCacheHelper.updateState(positionProperty)
			|| resizeBuffer;

	// Do we have to update the particle radii in the geometry buffer?
	bool updateRadii = _radiiCacheHelper.updateState(
			radiusProperty,
			typeProperty,
			defaultParticleRadius())
			|| resizeBuffer;

	// Do we have to update the particle colors in the geometry buffer?
	bool updateColors = _colorsCacheHelper.updateState(
			colorProperty,
			typeProperty,
			selectionProperty,
			transparencyProperty,
			positionProperty)
			|| resizeBuffer;

	// Do we have to update the particle shapes in the geometry buffer?
	bool updateShapes = _shapesCacheHelper.updateState(
			shapeProperty) || resizeBuffer;

	// Re-create the geometry buffer if necessary.
	if(recreateBuffer)
		_particleBuffer = renderer->createParticlePrimitive(shadingMode(), renderQuality, effectiveParticleShape, transparencyProperty != nullptr);

	// Re-size the geometry buffer if necessary.
	if(resizeBuffer)
		_particleBuffer->setSize(particleCount);

	// Update position buffer.
	if(updatePositions && positionProperty) {
		OVITO_ASSERT(positionProperty->size() == particleCount);
		_particleBuffer->setParticlePositions(positionProperty->constDataPoint3());
	}

	// Update radius buffer.
	if(updateRadii && particleCount) {
		if(radiusProperty) {
			// Take particle radii directly from the radius property.
			OVITO_ASSERT(radiusProperty->size() == particleCount);
			_particleBuffer->setParticleRadii(radiusProperty->constDataFloat());
		}
		else if(typeProperty) {
			// Assign radii based on particle types.
			OVITO_ASSERT(typeProperty->size() == particleCount);
			// Build a lookup map for particle type raii.
			const std::map<int,FloatType> radiusMap = typeProperty->radiusMap();
			// Skip the following loop if all per-type radii are zero. In this case, simply use the default radius for all particles.
			if(std::any_of(radiusMap.cbegin(), radiusMap.cend(), [](const std::pair<int,FloatType>& it) { return it.second != 0; })) {
				// Allocate memory buffer.
				std::vector<FloatType> particleRadii(particleCount, defaultParticleRadius());
				// Fill radius array.
				const int* t = typeProperty->constDataInt();
				for(auto c = particleRadii.begin(); c != particleRadii.end(); ++c, ++t) {
					auto it = radiusMap.find(*t);
					// Set particle radius only if the type's radius is non-zero.
					if(it != radiusMap.end() && it->second != 0)
						*c = it->second;
				}
				_particleBuffer->setParticleRadii(particleRadii.data());
			}
			else {
				// Assign a constant radius to all particles.
				_particleBuffer->setParticleRadius(defaultParticleRadius());
			}
		}
		else {
			// Assign a constant radius to all particles.
			_particleBuffer->setParticleRadius(defaultParticleRadius());
		}
	}

	// Update color buffer.
	if(updateColors && particleCount) {
		if(colorProperty && !selectionProperty && !transparencyProperty) {
			// Direct particle colors.
			OVITO_ASSERT(colorProperty->size() == particleCount);
			_particleBuffer->setParticleColors(colorProperty->constDataColor());
		}
		else {
			std::vector<Color> colors(particleCount);
			particleColors(colors, colorProperty, typeProperty, selectionProperty);
			if(!transparencyProperty) {
				_particleBuffer->setParticleColors(colors.data());
			}
			else {
				// Add alpha channel based on transparency particle property.
				std::vector<ColorA> colorsWithAlpha(particleCount);
				const FloatType* t = transparencyProperty->constDataFloat();
				auto c_in = colors.cbegin();
				for(auto c_out = colorsWithAlpha.begin(); c_out != colorsWithAlpha.end(); ++c_out, ++c_in, ++t) {
					c_out->r() = c_in->r();
					c_out->g() = c_in->g();
					c_out->b() = c_in->b();
					c_out->a() = FloatType(1) - (*t);
				}
				_particleBuffer->setParticleColors(colorsWithAlpha.data());
			}
		}
	}

	// Update shapes buffer.
	if(updateShapes && particleCount) {
		if(shapeProperty) {
			OVITO_ASSERT(shapeProperty->size() == particleCount);
			_particleBuffer->setParticleShapes(shapeProperty->constDataVector3());
		}
	}

	if(renderer->isPicking()) {
		OORef<ParticlePickInfo> pickInfo(new ParticlePickInfo(flowState));
		renderer->beginPickObject(contextNode, pickInfo);
	}

	_particleBuffer->render(renderer);

	if(renderer->isPicking()) {
		renderer->endPickObject();
	}
}
void MainWindow::on_actionSMOOTH_triggered()
{
    emit shadingMode(2);
}
void MainWindow::on_actionFLAT_triggered()
{
    emit shadingMode(1);
}