It's not possible to give you my node because is a property of QuanticDream. But it's possible to give you an exemple. :)
-- You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group. To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/130fb12f-ee46-4d61-8ef3-d5549408cd87%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
# ======================================================== # Import Modules # ======================================================== from maya import OpenMaya, OpenMayaMPx # ======================================================== # Math Utils Node # ======================================================== class RDIntersect(OpenMayaMPx.MPxNode): """ !@Brief Basic implementation of maya intersection for mesh (MFnMesh) My NodeId definition for maya plugin # # 1 -- 18 -- R # # 2 -- 4 -- D # # 3 -- Type -- 0 | DependNode - 1 | LocatorNode - 2 | DeformNode # # 4 -- Serie -- NN # # ex: 0x184001 """ # Static Variables kPluginNode = "rdIntersect" kPluginNodeID = OpenMaya.MTypeId(0x185134) kPluginNodeType = OpenMayaMPx.MPxNode.kDependNode INPUT_GEO = OpenMaya.MObject() RAY_ORIGIN = OpenMaya.MObject() RAY_DIR = OpenMaya.MObject() BOTH_SIDE = OpenMaya.MObject() MAX_DIST = OpenMaya.MObject() NO_INTERSECT = OpenMaya.MObject() HIT_POINT = OpenMaya.MObject() class _Hit(object): mfp_hit_point = OpenMaya.MFloatPoint() f_distance = 0.0 i_hit_face = 0 b_hit = False # ==================================================== # Init # ==================================================== @classmethod def creator(cls): return OpenMayaMPx.asMPxPtr(cls()) def __init__(self): super(RDIntersect, self).__init__() # Store last hit point, last distance and last direction of last hit # If you have intersect and next frame not # You keep this data for create arbitrary point position self._mfp_last_hit_point = OpenMaya.MFloatPoint() self._mv_last_ray_dir = OpenMaya.MFloatVector() self._f_last_distance = 0.0 self._i_last_hit_face = 0 @classmethod def initializer(cls): a_in_attributes = list() a_out_attributes = list() # ================================================ # Input attributes # Shape input input_geo_attr = OpenMaya.MFnGenericAttribute() cls.INPUT_GEO = input_geo_attr.create("inputGeom", "ing") input_geo_attr.setKeyable(False) input_geo_attr.setStorable(True) input_geo_attr.addDataAccept(OpenMaya.MFnData.kMesh) input_geo_attr.addDataAccept(OpenMaya.MFnData.kNurbsSurface) a_in_attributes.append(cls.INPUT_GEO) # Ray data # WARNING: createPoint of MFnNumericAttribute create MFloatVector # for create MVector use this prototype of MFnNumericAttribute # create ( # const MString &fullName, const MString &briefName, # const MObject &child1, const MObject &child2, const MObject &child3=MObject::kNullObj, # MStatus *ReturnStatus=NULL # ) ray_origin_attr = OpenMaya.MFnNumericAttribute() cls.RAY_ORIGIN = ray_origin_attr.createPoint("rayOrigin", "ro") ray_origin_attr.setKeyable(True) ray_origin_attr.setStorable(True) a_in_attributes.append(cls.RAY_ORIGIN) ray_origin_attr = OpenMaya.MFnNumericAttribute() cls.RAY_DIR = ray_origin_attr.createPoint("rayDirection", "rd") ray_origin_attr.setKeyable(True) ray_origin_attr.setStorable(True) a_in_attributes.append(cls.RAY_DIR) # Intersect Options both_side_attr = OpenMaya.MFnNumericAttribute() cls.BOTH_SIDE = both_side_attr.create("bothSide", "bs", OpenMaya.MFnNumericData.kBoolean, True) both_side_attr.setKeyable(True) both_side_attr.setStorable(True) a_in_attributes.append(cls.BOTH_SIDE) max_dist_attr = OpenMaya.MFnNumericAttribute() cls.MAX_DIST = max_dist_attr.create("maxDistance", "md", OpenMaya.MFnNumericData.kDouble, 1000.0) max_dist_attr.setMin(1e-12) max_dist_attr.setKeyable(True) max_dist_attr.setStorable(True) a_in_attributes.append(cls.MAX_DIST) no_intersect_attr = OpenMaya.MFnEnumAttribute() cls.NO_INTERSECT = no_intersect_attr.create("noIntersect", "ni", 1) no_intersect_attr.setKeyable(True) no_intersect_attr.setStorable(True) no_intersect_attr.addField("Nothing", 0) no_intersect_attr.addField("KeepLastPos", 1) no_intersect_attr.addField("KeppLastDist", 2) a_in_attributes.append(cls.NO_INTERSECT) # ================================================ # Output attributes hit_point_attr = OpenMaya.MFnNumericAttribute() cls.HIT_POINT = hit_point_attr.createPoint("hitPoint", "hp") hit_point_attr.setKeyable(False) hit_point_attr.setStorable(False) a_out_attributes.append(cls.HIT_POINT) # ToDo # If you want to calculate hit rotation create rotation attribute or Matrix attribute # ================================================ # Add attributes for mo_attribute in (a_in_attributes + a_out_attributes): cls.addAttribute(mo_attribute) # ================================================ # Set the attribute dependencies # https://help.autodesk.com/view/MAYAUL/2018/ENU/?guid=__cpp_ref_class_m_px_node_html # This method specifies that a particular input attribute affects a specific output attribute. for mo_out_attr in a_out_attributes: for mo_in_attr in a_in_attributes: cls.attributeAffects(mo_in_attr, mo_out_attr) # ==================================================== # Compute # ==================================================== def compute(self, plug, data): # Compute only if plug is output attribute if plug != self.HIT_POINT: return # Get input datas h_input_geom = data.inputValue(self.INPUT_GEO) mfv_ray_origin = data.inputValue(self.RAY_ORIGIN).asFloatVector() mfv_ray_dir = data.inputValue(self.RAY_DIR).asFloatVector() b_both_side = data.inputValue(self.BOTH_SIDE).asBool() f_max_distance = data.inputValue(self.MAX_DIST).asDouble() i_no_intersect = data.inputValue(self.NO_INTERSECT).asShort() # Get Shape if h_input_geom.type() not in [OpenMaya.MFnData.kMesh, OpenMaya.MFnData.kNurbsSurface]: raise Exception("Invalid shape data given. Accepted shape: Mesh, NurbsSurface.") if h_input_geom.type() == OpenMaya.MFnData.kNurbsSurface: raise Exception("NurbsSurface intersect not implemented yet.") mfn_mesh = OpenMaya.MFnMesh(h_input_geom.asMesh()) hit = self._mesh_intersection(mfn_mesh, mfv_ray_origin, mfv_ray_dir, b_both_side, f_max_distance) # Intersection found # Store data if hit.b_hit is True: self._mfp_last_hit_point = hit.mfp_hit_point self._mv_last_ray_dir = mfv_ray_dir self._f_last_distance = hit.f_distance self._i_last_hit_face = hit.i_hit_face # No intersect found # Get last data stored else: # Keep last position if i_no_intersect == 1: hit.mfp_hit_point = self._mfp_last_hit_point hit.f_distance = self._f_last_distance hit.i_hit_face = self._i_last_hit_face # Keep last distance and calculate new position from distance if i_no_intersect == 2: hit.mfp_hit_point = mfv_ray_origin + mfv_ray_dir.normal() * self._f_last_distance hit.f_distance = self._f_last_distance hit.i_hit_face = self._i_last_hit_face # Get output Position mfv_hit_point = OpenMaya.MFloatVector(hit.mfp_hit_point) # ToDo # Get orientation with normal and tangent of polygon from hitFace ID # ToDo: # Smooth interpollation between hit point and ray origin if no intersect found # Output Value h_hit_point = data.outputValue(self.HIT_POINT) h_hit_point.setMFloatVector(mfv_hit_point) h_hit_point.setClean() # Clean data.setClean(plug) # ==================================================== # Misc # ==================================================== @staticmethod def _mesh_intersection(mfn_mesh, mfv_ray_origin, mfv_ray_dir, b_both_side, f_max_distance): """ !@Brief Get mesh intersection @type mfn_mesh: OpenMaya.MFnMesh @param mfn_mesh: MFnMesh for get intersection @type mfv_ray_origin: OpenMaya.MFloatPoint @param mfv_ray_origin: Origin of ray intersection @type mfv_ray_dir: OpenMaya.MFloatVector @param mfv_ray_dir: Ray direction for intersection @type b_both_side: bool @param b_both_side: Set True if you want to check both side of rayDir. @type f_max_distance: float @param f_max_distance: Intersection distance tolerence. @rtype: MFloatPoint, int @return: Point and face id of intersection. None if no intersection found """ hit = RDIntersect._Hit() # Hit point pointer mfp_hit_point = OpenMaya.MFloatPoint() # Face ID pointer hit_face_su = OpenMaya.MScriptUtil() hit_face_su.createFromInt(0) ptr_hit_face = hit_face_su.asIntPtr() # Other options f_tolerence = 1e-6 a_face_ids = None a_tril_ids = None b_ids_sorted = False f_hit_ray_param = None i_hit_triangle = None f_hit_bary_1 = None f_hit_bary_2 = None ms_space = OpenMaya.MSpace.kWorld # Intersection acceleration by voxelization # Auto generation of grid map_accel_param = mfn_mesh.autoUniformGridParams() # Intersect b_hit = mfn_mesh.closestIntersection( OpenMaya.MFloatPoint(mfv_ray_origin), mfv_ray_dir.normal(), a_face_ids, a_tril_ids, b_ids_sorted, ms_space, f_max_distance, b_both_side, map_accel_param, mfp_hit_point, f_hit_ray_param, ptr_hit_face, i_hit_triangle, f_hit_bary_1, f_hit_bary_2, f_tolerence ) if b_hit is True: hit.b_hit = True hit.mfp_hit_point = mfp_hit_point hit.f_distance = (OpenMaya.MFloatVector(mfp_hit_point) - mfv_ray_origin).length() hit.i_hit_face = hit_face_su.getInt(ptr_hit_face) return hit # ======================================================== # Initialize Plugin # ======================================================== # load def initializePlugin(m_object): plugin = OpenMayaMPx.MFnPlugin( m_object, "Intersect Exemple\n\tRemi Deletrain -- remi.deletr...@gmail.com", "1.0", "Any" ) try: plugin.registerNode( RDIntersect.kPluginNode, RDIntersect.kPluginNodeID, RDIntersect.creator, RDIntersect.initializer, RDIntersect.kPluginNodeType ) except Exception, err: print err.message raise RuntimeError("Failed to register command: %s\n" % RDIntersect.kPluginNode) # Unload def uninitializePlugin(m_object): plugin = OpenMayaMPx.MFnPlugin(m_object) try: plugin.deregisterNode(RDIntersect.kPluginNodeID) except Exception, err: print err.message raise RuntimeError("Failed to unregister node: %s\n" % RDIntersect.kPluginNode)
rdIntersectExemple.ma
Description: Binary data