Пример #1
0
        //
        // Description
        //
        //    Transforms the given components. This method is used by
        //    the move, rotate, and scale tools in component mode.
        //    The bounding box has to be updated here, so do the normals and
        //    any other attributes that depend on vertex positions.
        //
        // Arguments
        //    mat           - matrix to transform the components by
        //    componentList - list of components to be transformed,
        //                    or an empty list to indicate the whole surface
        //    cachingMode   - how to use the supplied pointCache
        //    pointCache    - if non-null, save or restore points from this list base
        //                      on the cachingMode
        //
        public override void transformUsing(MMatrix mat,
            MObjectArray componentList,
            MVertexCachingMode cachingMode,
            MPointArray pointCache)
        {
            apiMeshGeom geomPtr = meshGeom();

            bool savePoints = (cachingMode == MVertexCachingMode.kSavePoints);
            int i = 0, j = 0;
            uint len = componentList.length;

            if (cachingMode == MVertexCachingMode.kRestorePoints) {
                // restore the points based on the data provided in the pointCache attribute
                //
                uint cacheLen = pointCache.length;
                if (len > 0) {
                    // traverse the component list
                    //
                    for ( i = 0; i < len && j < cacheLen; i++ )
                    {
                        MObject comp = componentList[i];
                        MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp );
                        int elemCount = fnComp.elementCount;
                        for ( int idx=0; idx<elemCount && j < cacheLen; idx++, ++j ) {
                            int elemIndex = fnComp.element( idx );
                            geomPtr.vertices[elemIndex] = pointCache[j];
                        }
                    }
                } else {
                    // if the component list is of zero-length, it indicates that we
                    // should transform the entire surface
                    //
                    len = geomPtr.vertices.length;
                    for ( int idx = 0; idx < len && j < cacheLen; ++idx, ++j ) {
                        geomPtr.vertices[idx] = pointCache[j];
                    }
                }
            } else {
                // Transform the surface vertices with the matrix.
                // If savePoints is true, save the points to the pointCache.
                //
                if (len > 0) {
                    // Traverse the componentList
                    //
                    for ( i=0; i<len; i++ )
                    {
                        MObject comp = componentList[i];
                        MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp );
                        uint elemCount = (uint)fnComp.elementCount;

                        if (savePoints && 0 == i) {
                            pointCache.sizeIncrement = elemCount;
                        }
                        for ( int idx=0; idx<elemCount; idx++ )
                        {
                            int elemIndex = fnComp.element( (int)idx );
                            if (savePoints) {
                                pointCache.append(geomPtr.vertices[elemIndex]);
                            }

                            geomPtr.vertices[elemIndex].multiplyEqual( mat );
                            geomPtr.normals[idx] = geomPtr.normals[idx].transformAsNormal( mat );
                        }
                    }
                } else {
                    // If the component list is of zero-length, it indicates that we
                    // should transform the entire surface
                    //
                    len = geomPtr.vertices.length;
                    if (savePoints) {
                        pointCache.sizeIncrement = len;
                    }
                    for ( int idx = 0; idx < len; ++idx ) {
                        if (savePoints) {
                            pointCache.append(geomPtr.vertices[idx]);
                        }
                        geomPtr.vertices[idx].multiplyEqual( mat );
                        geomPtr.normals[idx] = geomPtr.normals[idx].transformAsNormal( mat );

                    }
                }
            }
            // Retrieve the value of the cached surface attribute.
            // We will set the new geometry data into the cached surface attribute
            //
            // Access the datablock directly. This code has to be efficient
            // and so we bypass the compute mechanism completely.
            // NOTE: In general we should always go though compute for getting
            // and setting attributes.
            //
            MDataBlock datablock = _forceCache();

            MDataHandle cachedHandle = datablock.outputValue( cachedSurface );
            apiMeshData cached = cachedHandle.asPluginData as apiMeshData;

            MDataHandle dHandle = datablock.outputValue( mControlPoints );

            // If there is history then calculate the tweaks necessary for
            // setting the final positions of the vertices.
            //
            if ( hasHistory() && (null != cached) ) {
                // Since the shape has history, we need to store the tweaks (deltas)
                // between the input shape and the tweaked shape in the control points
                // attribute.
                //
                buildControlPoints( datablock, (int)geomPtr.vertices.length );

                MArrayDataHandle cpHandle = new MArrayDataHandle( dHandle );

                // Loop through the component list and transform each vertex.
                //
                for ( i=0; i<len; i++ )
                {
                    MObject comp = componentList[i];
                    MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp );
                    int elemCount = fnComp.elementCount;
                    for ( int idx=0; idx<elemCount; idx++ )
                    {
                        int elemIndex = fnComp.element( idx );
                        cpHandle.jumpToElement( (uint)elemIndex );
                        MDataHandle pntHandle = cpHandle.outputValue();
                        double[] pnt = pntHandle.Double3;

                        MPoint oldPnt = cached.fGeometry.vertices[elemIndex];
                        MPoint newPnt = geomPtr.vertices[elemIndex];
                        MVector offset = newPnt.minus( oldPnt );

                        pnt[0] += offset[0];
                        pnt[1] += offset[1];
                        pnt[2] += offset[2];

                        pntHandle.Double3 = pnt;
                    }
                }
            }

            // Copy outputSurface to cachedSurface
            //
            if ( null == cached ) {
                MGlobal.displayInfo("NULL cachedSurface data found");
            }
            else {
                cached.fGeometry = geomPtr;
            }

            MPlug pCPs = new MPlug( thisMObject(), mControlPoints );
            pCPs.setValue(dHandle);

            // Moving vertices will likely change the bounding box.
            //
            computeBoundingBox( datablock );

            // Tell Maya the bounding box for this object has changed
            // and thus "boundingBox()" needs to be called.
            //
            childChanged( MChildChanged.kBoundingBoxChanged );
        }
Пример #2
0
        //
        // Description
        //
        //    Transforms the given components. This method is used by
        //    the move, rotate, and scale tools in component mode when the
        //    tweaks for the shape are stored on a separate tweak node.
        //    The bounding box has to be updated here, so do the normals and
        //    any other attributes that depend on vertex positions.
        //
        // Arguments
        //    mat           - matrix to transform the components by
        //    componentList - list of components to be transformed,
        //                    or an empty list to indicate the whole surface
        //    cachingMode   - how to use the supplied pointCache
        //    pointCache    - if non-null, save or restore points from this list base
        //                      on the cachingMode
        //    handle	    - handle to the attribute on the tweak node where the
        //                      tweaks should be stored
        //
        public override void tweakUsing( MMatrix mat,
            MObjectArray componentList,
            MVertexCachingMode cachingMode,
            MPointArray pointCache,
            MArrayDataHandle handle)
        {
            apiMeshGeom geomPtr = meshGeom();

            bool savePoints    = (cachingMode == MVertexCachingMode.kSavePoints);
            bool updatePoints  = (cachingMode == MVertexCachingMode.kUpdatePoints);

            MArrayDataBuilder builder = handle.builder();

            MPoint delta = new MPoint();
            MPoint currPt = new MPoint();
            MPoint newPt = new MPoint();
            int i=0;
            uint len = componentList.length;
            int cacheIndex = 0;
            uint cacheLen = (null != pointCache) ? pointCache.length : 0;

            if (cachingMode == MVertexCachingMode.kRestorePoints) {
                // restore points from the pointCache
                //
                if (len > 0) {
                    // traverse the component list
                    //
                    for ( i=0; i<len; i++ )
                    {
                        MObject comp = componentList[i];
                        MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp );
                        int elemCount = fnComp.elementCount;
                        for ( int idx=0; idx<elemCount && cacheIndex < cacheLen; idx++, cacheIndex++) {
                            int elemIndex = fnComp.element( idx );
                            MDataHandle hdl = builder.addElement((uint)elemIndex);
                            double[] pt = hdl.Double3;
                            MPoint cachePt = pointCache[cacheIndex];
                            pt[0] += cachePt.x;
                            pt[1] += cachePt.y;
                            pt[2] += cachePt.z;
                            hdl.Double3 = pt;
                        }
                    }
                } else {
                    // if the component list is of zero-length, it indicates that we
                    // should transform the entire surface
                    //
                    len = geomPtr.vertices.length;
                    for ( uint idx = 0; idx < len && idx < cacheLen; ++idx ) {
                        MDataHandle hdl = builder.addElement(idx);
                        double[] pt = hdl.Double3;
                        MPoint cachePt = pointCache[cacheIndex];
                        pt[0] += cachePt.x;
                        pt[1] += cachePt.y;
                        pt[2] += cachePt.z;
                        hdl.Double3 = pt;
                    }
                }
            } else {
                // Tweak the points. If savePoints is true, also save the tweaks in the
                // pointCache. If updatePoints is true, add the new tweaks to the existing
                // data in the pointCache.
                //
                if (len > 0) {
                    for ( i=0; i<len; i++ )
                    {
                        MObject comp = componentList[i];
                        MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp );
                        int elemCount = fnComp.elementCount;
                        if (savePoints) {
                            pointCache.sizeIncrement = (uint)elemCount;
                        }
                        for ( int idx=0; idx<elemCount; idx++ )
                        {
                            int elemIndex = fnComp.element( idx );
                            MDataHandle hdl = builder.addElement((uint)elemIndex);
                            double[] pt = hdl.Double3;
                            currPt = newPt = geomPtr.vertices[elemIndex];
                            newPt.multiplyEqual( mat );
                            delta.x = newPt.x - currPt.x;
                            delta.y = newPt.y - currPt.y;
                            delta.z = newPt.z - currPt.z;
                            pt[0] += delta.x;
                            pt[1] += delta.y;
                            pt[2] += delta.z;
                            hdl.Double3 = pt;
                            if (savePoints) {
                                // store the points in the pointCache for undo
                                //
                                pointCache.append(delta*(-1.0));
                            } else if (updatePoints && cacheIndex < cacheLen) {
                                MPoint cachePt = pointCache[cacheIndex];
                                cachePt[0] -= delta.x;
                                cachePt[1] -= delta.y;
                                cachePt[2] -= delta.z;
                                cacheIndex++;
                            }
                        }
                    }
                } else {
                    // if the component list is of zero-length, it indicates that we
                    // should transform the entire surface
                    //
                    len = geomPtr.vertices.length;
                    if (savePoints) {
                        pointCache.sizeIncrement = len;
                    }
                    for ( int idx = 0; idx < len; ++idx ) {
                        MDataHandle hdl = builder.addElement((uint)idx);
                        double[] pt = hdl.Double3;
                        currPt = newPt = geomPtr.vertices[idx];
                        newPt.multiplyEqual( mat );
                        delta.x = newPt.x - currPt.x;
                        delta.y = newPt.y - currPt.y;
                        delta.z = newPt.z - currPt.z;
                        pt[0] += delta.x;
                        pt[1] += delta.y;
                        pt[2] += delta.z;
                        hdl.Double3 = pt;
                        if (savePoints) {
                            // store the points in the pointCache for undo
                            //
                            pointCache.append(delta*-1.0);
                        } else if (updatePoints && idx < cacheLen) {
                            MPoint cachePt = pointCache[idx];
                            cachePt[0] -= delta.x;
                            cachePt[1] -= delta.y;
                            cachePt[2] -= delta.z;
                        }
                    }
                }
            }
            // Set the builder into the handle.
            //
            handle.set(builder);

            // Tell Maya the bounding box for this object has changed
            // and thus "boundingBox()" needs to be called.
            //
            childChanged( MChildChanged.kBoundingBoxChanged );
        }
Пример #3
0
		public override void tweakUsing( MMatrix mat,
										 MObjectArray componentList,
										 MVertexCachingMode cachingMode,
										 MPointArray pointCache,
										 MArrayDataHandle handle )
		//
		// Description
		//
		//    Transforms the given components. This method is used by
		//    the move, rotate, and scale tools in component mode when the
		//    tweaks for the shape are stored on a separate tweak node.
		//    The bounding box has to be updated here, so do the normals and
		//    any other attributes that depend on vertex positions.
		//
		// Arguments
		//    mat           - matrix to transform the components by
		//    componentList - list of components to be transformed,
		//                    or an empty list to indicate the whole surface
		//    cachingMode   - how to use the supplied pointCache
		//    pointCache    - if non-null, save or restore points from this list base
		//					  on the cachingMode
		//    handle	    - handle to the attribute on the tweak node where the
		//					  tweaks should be stored
		//
		{
			apiMeshGeom geomPtr = meshGeom();

			bool savePoints    = (cachingMode == MVertexCachingMode.kSavePoints);
			bool updatePoints  = (cachingMode == MVertexCachingMode.kUpdatePoints);

			MArrayDataBuilder builder = handle.builder();

			MPoint delta = new MPoint();
			MPoint currPt = new MPoint();
			MPoint newPt = new MPoint();
			int i=0;
			uint len = componentList.length;
			int cacheIndex = 0;
			uint cacheLen = (null != pointCache) ? pointCache.length : 0;

			if (cachingMode == MVertexCachingMode.kRestorePoints) {
				// restore points from the pointCache
				//
				if (len > 0) {
					// traverse the component list
					//
					for ( i=0; i<len; i++ )
					{
						MObject comp = componentList[i];
						MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp );
						int elemCount = fnComp.elementCount;
						for ( int idx=0; idx<elemCount && cacheIndex < cacheLen; idx++, cacheIndex++) {
							int elemIndex = fnComp.element( idx );
                            MDataHandle hdl = builder.addElement((uint)elemIndex);
							double[] pt = hdl.Double3;
							MPoint cachePt = pointCache[cacheIndex];
							pt[0] += cachePt.x;
							pt[1] += cachePt.y;
							pt[2] += cachePt.z;
                            hdl.Double3 = pt;
						}
					}
				} else {
					// if the component list is of zero-length, it indicates that we
					// should transform the entire surface
					//
					len = geomPtr.vertices.length;
					for ( uint idx = 0; idx < len && idx < cacheLen; ++idx ) {
                        MDataHandle hdl = builder.addElement(idx);
                        double[] pt = hdl.Double3;
						MPoint cachePt = pointCache[cacheIndex];
						pt[0] += cachePt.x;
						pt[1] += cachePt.y;
						pt[2] += cachePt.z;
                        hdl.Double3 = pt;
					}
				}
			} else {
				// Tweak the points. If savePoints is true, also save the tweaks in the
				// pointCache. If updatePoints is true, add the new tweaks to the existing
				// data in the pointCache.
				//
				if (len > 0) {
					for ( i=0; i<len; i++ )
					{
						MObject comp = componentList[i];
						MFnSingleIndexedComponent fnComp = new MFnSingleIndexedComponent( comp );
						int elemCount = fnComp.elementCount;
						if (savePoints) {
							pointCache.sizeIncrement = (uint)elemCount;
						}
						for ( int idx=0; idx<elemCount; idx++ )
						{
							int elemIndex = fnComp.element( idx );
                            MDataHandle hdl = builder.addElement((uint)elemIndex);
							double[] pt = hdl.Double3;
							currPt = newPt = geomPtr.vertices[elemIndex];
							newPt.multiplyEqual( mat );
							delta.x = newPt.x - currPt.x;
							delta.y = newPt.y - currPt.y;
							delta.z = newPt.z - currPt.z;
							pt[0] += delta.x;
							pt[1] += delta.y;
							pt[2] += delta.z;
                            hdl.Double3 = pt;
							if (savePoints) {
								// store the points in the pointCache for undo
								//
								pointCache.append(delta*(-1.0));
							} else if (updatePoints && cacheIndex < cacheLen) {
								MPoint cachePt = pointCache[cacheIndex];
								cachePt[0] -= delta.x;
								cachePt[1] -= delta.y;
								cachePt[2] -= delta.z;
								cacheIndex++;
							}
						}
					}
				} else {
					// if the component list is of zero-length, it indicates that we
					// should transform the entire surface
					//
					len = geomPtr.vertices.length;
					if (savePoints) {
						pointCache.sizeIncrement = len;
					}
					for ( int idx = 0; idx < len; ++idx ) {
                        MDataHandle hdl = builder.addElement((uint)idx);
						double[] pt = hdl.Double3;
						currPt = newPt = geomPtr.vertices[idx];
						newPt.multiplyEqual( mat );
						delta.x = newPt.x - currPt.x;
						delta.y = newPt.y - currPt.y;
						delta.z = newPt.z - currPt.z;
						pt[0] += delta.x;
						pt[1] += delta.y;
						pt[2] += delta.z;
                        hdl.Double3 = pt;
						if (savePoints) {
							// store the points in the pointCache for undo
							//
							pointCache.append(delta*-1.0);
						} else if (updatePoints && idx < cacheLen) {
							MPoint cachePt = pointCache[idx];
							cachePt[0] -= delta.x;
							cachePt[1] -= delta.y;
							cachePt[2] -= delta.z;
						}
					}
				}
			}
			// Set the builder into the handle.
			//
			handle.set(builder);

			// Tell Maya the bounding box for this object has changed
			// and thus "boundingBox()" needs to be called.
			//
			childChanged( MChildChanged.kBoundingBoxChanged );
		}