Maya C++ API Programming Tips

source : http://wanochoi.com/?page_id=1588

How to handle the multiple outputs of a DG node

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
MStatus MyNode::initialize()
{
   MFnNumericAttribute nAttr;
   outputsObj = nAttr.create( "outputs", "outputs", MFnNumericData.kFloat, 0.f );
   nAttr.setArray( true );
   addAttribute( outputsObj );
   ...
}
MStatus MyNode::compute( const MPlug& plug, MDataBlock& data )
{
   if( plug != outputsObj ) { return MS::kUnknownParameter; }
   MArrayDataHandle outputsHnd = data.outputArrayValue( outputsObj );
   const int nOutputs = (int)outputsHnd.elementCount();
   for( int i=0; i<100; ++i )
   {
      outputsHnd.jumpToElement( i );
      outputsHnd.outputValue().set( i );
   }
   outputsHnd.setAllClean();
   return MS::kSuccess;  
}

How to capture the current viewport as an image file

?
1
2
3
4
MImage image;
M3dView view = M3dView::active3dView();
view.readColorBuffer( image, true );
image.writeToFile( "snapshot.jpg", "jpg" );

How to save the current frame buffer to a JPG file

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GLint viewport[4];
glGetIntegerv( GL_VIEWPORT, viewport );
int width = viewport[2];
int height = viewport[3];
int depth = 4;
unsigned char* pixels = new unsigned int[width*height*depth];
glReadBuffer( GL_FRONT );
glReadPixels( 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
MImage image;
image.setPixels( pixels, width, height );
image.writeToFile( "snapshot.jopg", "jpg" );
delete[] pixels;

How to set the names of a custom DG node and its parent node

?
1
2
3
4
5
6
7
8
9
void myNode::postConstructor()
{
   MPxNode::postConstructor();
   MObject thisMObj = thisMObject();
   MFnDependencyNode nodeFn;
   nodeFn.setObject( thisMObj );
   nodeFn.setName( "myNodeShape#" );
}

How to compile my source code conditionally according to the Maya API version

?
1
2
3
4
5
6
7
#if MAYA_API_VERSION &amp;gt;= 201300
...
#elif MAYA_API_VERSION &amp;gt;= 201400
...
#elif MAYA_API_VERSION &amp;gt;= 201500
...
#endif

How to get the current Maya version

?
1
2
MString mayaVer = MGlobal::mayaVersion();
int apiVer = MGlobal::apiVersion();

How to avoid the conflict with Cuda

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
#define short2  MAYA_short2
#define short3  MAYA_short3
#define long2   MAYA_long2
#define long3   MAYA_long3
#define int2    MAYA_int2
#define int3    MAYA_int3
#define float2  MAYA_float2
#define float3  MAYA_float3
#define double2 MAYA_double2
#define double3 MAYA_double3
#define double4 MAYA_double4
#include &amp;lt;cuda.h&amp;gt;
...

How to set the MFloatPoint from a MPoint

?
1
2
3
MPoint dp; // double type
MFloatPoint fp; // float type
fp.setCast( dp );

How to get the pixel values of an image

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
MImage img;
img.readFromFile( "filePathName" ); // load from a file
int w=0, h=0; // image width, height
img.getSize( w, h );
int d = img.depth(); // image depth
unsigned char* c = (unsigned char*)NULL;
if( img.pixelType() == MImage::kByte )
{
   c = img.pixels();
}
for( int j=0; j&amp;lt;h; ++j )
for( int i=0; i&amp;lt;w; ++i )
{{
   int idx = d*(i+j*w);
   unsigned char pixelVal[4]; // RGB(d=3) or RGBA(d=4)
   for( int k=0; k&amp;lt;d; ++k )
   {
      pixelVal[k] = c[idx++];
   }
   ...
}}

How to get the DAG path from a node name

?
1
2
3
4
5
6
7
MString nodeName( "nodeName" );
MDagPath dagPath;
MSelectionList sList;
if( MGlobal::getSelectionListByName( nodeName, sList ) )
{
   sList.getDagPath( 0, dagPath );
}

How to get the DG node object from a node name

?
1
2
3
4
5
6
7
MString nodeName( "nodeName" );
MObject nodeObj;
MSelectionList sList;
if( MGLobal::getSelectionListByName( nodeName, sList ) )
{
   sList.getDependNode( 0, nodeObj );
}

How to get the DAG path from a DAG node object

?
1
2
3
4
MObject dagNodeObj = ...;
MDagPath dagPath;
MFnDagNode dagFn( dagNodeObj );
dagFn.getPath( dagPath );

How to get the node name from a node object

?
1
2
3
4
5
6
7
8
9
10
MObject nodeObj = ...;
MString nodeName;
if( nodeObj.hasFn( MFn::kDagNode ) ) {
   MFnDagNode dagNodeFn( nodeObj );
   nodeName = dagNode.fullPathName();
} else if( nodeObj.hasFn( MFn::kDependencyNode ) ) {
   MFnDependencyNode dgNodeFn( nodeObj );
   nodeName = dgNodeFn.name();
}

How to get the parent DAG node object

?
1
2
3
4
5
6
7
MObject parentDagNodeObj;
MFnDagNode dagFn( thisMObject() );
MObject obj = dagFn.parent( 0 );
if( !obj.isNull() )
{
   parentDagNodeObj = obj;
}

How to get the shape node DAG path from a transform DAG path

?
1
2
3
MDagPath xformDagPath = ...
MDagPath shapeDagPath = xformDagPath;
shapeDagPath.extendToShape();

How to get the DAG paths of selected mesh shape nodes

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
MDagPathArray dagPaths;
MSelectionList sList;
MGlobal::getActiveSelectionList( sList );
MItSelectionList itr( sList, MFn::kMesh );
for( ; !itr.isDone(); itr.next() )
{
   MDagPath dagPath;
   itr.getDagPath( dagPath );
   MFnDagNode dagFn( dagPath );
   if( dagFn.isIntermediateObject() ) { continue; }
   dagPaths.append( dagPath );
}

How to get the all of NURBS curve node objects in the current scene

?
1
2
3
4
5
6
MObjectArray curveObjs;
MItDag itr( MItDag::kDepthFirst, MFn::kNurbsCurve );
for( ; !itr.isDone(); itr.next() )
{
   curveObjs.append( itr.item() );
}

How to get the list of a selected mesh polygons

?
1
2
3
4
5
6
7
8
9
10
11
12
MIntArray selectedPolygonList;
MSelectionList sList;
MGlobal::getActiveSelectionList( sList );
MItSelectionList sItr( sList, MFn::kMeshPolygonComponent );
MDagPath dagPath;
MObject componentObj;
sItr.getDagPath( dagPath, componentObj );
MFnSingleIndexedComponent sCompFn( componentObj );
sCompFn.getElements( selectedPolygonList );

How to get the all of fields in the current scene

?
1
2
3
4
5
6
MItDag itr( MItDag::kDepthFirst, MFn::kField );
for( ; !itr.isDone(); itr.next() )
{
   MFnField fieldFn( itr.item() );
   ...
}

How to get the world matrix of the current DAG node

?
1
2
3
4
5
6
7
8
MObject thisNodeObj = thisMObject();
MFnDependencyNode thisNodeFn( thisNodeObj );
MObject worldMatrixObj = thisNodeFn.attribute( "worldMatrix" );
MPlug worldMatrixPlg( thisNodeObj, worldMatrixObj );
worldMatrixPlg = worldMatrixPlg.elementByLogicalIndex( 0 );
worldMatrixPlg.getValue( worldMatrixObj );
MFnMatrixData worldMatrixData( worldMatrixObj );
Matrix worldMatrix = worldMatrixData.matrix();

How to connect the output plug to the parent automatically when a custom locator node is created

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class MyLocator
{
   ...
   bool connected;
   ...
};
MyLocator::MyLocator()
{
   connected = false;
}
void MyLocator::draw( M3dView&amp;amp; view, ...)
{
   if( !connected )
   {
      MObject thisNodeObj = thisMObject();
      MFnDagNode dagFn( thisNodeObj );
      MObject parentNodeObj = dagFn.parent( 0 );
      dagFn.setObject( parentNodeObj );
      MPlug parentPlg = dagFn.findPlug( "plugName" );
      MPlug outputPlg = MPlug( thisNodeObj, outputObj );
      if( !outputPlg.isConnected() )
      {
         MDGModifier dgMod;
         dgMod.connect( outputPlg, parentPlg );
         dgMod.doIt();
         connected = true;
      }
   }
   ...
}

How to make a custom locator node un-selectable

?
1
2
3
4
5
void MyLocator::draw( M3dView&amp;amp; view, ...)
{
   if( view.selectMode() ) { return; }
   ...
}

How to detect which input attribute is changed

?
1
2
3
4
5
6
7
8
9
MStatus MyCustomNode::compute( const MPlug&amp;amp; plug, MDataBlock&amp;amp; data )
{
   if( plug != outputObj ) { return MS::kUnknownParameter; }
   bool inputIsChanged = !data.isClean( inputObj );
   float input = data.inputValue( inputObj ).asFloat();
   ...
}

Note) It doesn’t work when inputObj is array type.

How to detect whether the current state is batch mode

?
1
2
3
4
if( MGlobal::mayaState() == MGlobal::kBatch )
{
   ...
}

How to detect whether the current viewport is Viewport 2.0

?
1
2
3
4
5
M3dView view = M3dView::active3dView();
if( view.getRendererName() == M3dView::kViewport2Renderer )
{
   ...
}

How not to draw a custom locator node while mouse interactions (>=2015)

?
1
2
3
4
5
6
7
8
void MyLocator::draw( M3dView&amp;amp; view, ...)
{
   if( MHWRender::MFrameContext::inUserInteraction()
    || MHWRender::MFrameContext::userChangingViewContext() )
   {
      ...
   }
}

How to draw a text in draw() of a custom locator node

?
1
2
3
4
5
6
7
8
void MyLocator::draw( M3dView&amp;amp; view, ...)
{
   ...
   view.beginGL();
   view.drawText( MString("text"), MPoint(0,0,0), M3dView::kLeft );
   view.endGL();
   ...
}

How to copy the input mesh to the output mesh in compute() of a custom node

?
1
2
3
4
5
6
7
8
9
10
MStatus MyNode::compute( const MPlug&amp;amp; plug, MDataBlock&amp;amp; data )
{
   ...
   MFnMesh newMeshFn;
   MFnMeshData dataCreator;
   MObject newMeshData = dataCreator.create();
   newMeshFn.copy( data.inputValue( inMeshObj ).asMeshTransformed(), newMeshData );
   data.outputValue( outMeshObj ).set( newMeshData );
   ...
}

How to deform the input mesh in compute() of a custom node like such a deformer

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MStatus MyNode::compute( const MPlug&amp;amp; plug, MDataBlock&amp;amp; data )
{
   ...
   MPointArray deformedPoints = ...
   MFnMesh newMeshFn;
   MFnMeshData dataCreator;
   MObject newMeshData = dataCreator.create();
   newMeshFn.copy( data.inputValue( inMeshObj ).asMeshTransformed(), newMeshData );
   newMeshFn.setPoints( deformedPoints );
   data.outputValue( outMeshObj ).set( newMeshData );
   ...
}

How to handle array attribute

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class MyCustomNode
{
   ...
   MObject valuesObj;
   ...
   MDoubleArray values;
};
MObject MyCustomNode::valuesObj;
MStatus MyCustomNode::initialize()
{
   ...
   valuesObj = tAttr.create( "values", "values", MFnData::kDoubleArray );
   ...
}
MStatus MyCustomNode::compute( const MPlug&amp;amp; plug, MDataBlock&amp;amp; data )
{
   ...
   // get
   MFnDoubleArrayData arrayData;
   MObject dataObj = data.inputValue( valuesObj ).data();
   arrayData.setObject( dataObj );
   int numValues = 100;
   // set
   if( arrayData.length() != numValues )
   {
      MDoubleArray array( numValues, 0.0 );
      dataObj = arrayData.create( array );
      data.outputValue( valuesObj ).set( dataObj );
   }
   ...
}
// MEL
makePaintable -at doubleArray MyCustomNode values;
setAttr MyCustomNode1.values -type doubleArray 3 1.0 2.0 3.0;

How to get the value of an attribute anywhere in a custom node

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
MObject thisNodeObj = thisMObject();
double  v0 = MPlug( thisNodeObj, attr0Obj ).asDouble();
float   v1 = MPlug( thisNodeObj, attr1Obj ).asFloat();
int     v2 = MPlug( thisNodeObj, attr2Obj ).asInt();
short   v3 = MPlug( thisNodeObj, attr3Obj ).asShort();
bool    v4 = MPlug( thisNodeObj, attr4Obj ).asBool();
MTime   v5 = MPlug( thisNodeObj, attr5Obj ).asMTime();
char    v6 = MPlug( thisNodeObj, attr6Obj ).asChar();
MString v7 = MPlug( thisNodeObj, attr7Obj ).asString();
MColor c;
MPlug plg( thisNodeObj, attrObj );
plg.child(0).getValue( c.r );
plg.child(1).getValue( c.g );
plg.child(2).getValue( c.b );

How to get the pointer of the other connected node

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
OtherNodeClassName* otherNodePtr = (OtherNodeClassName*)NULL;
MObject thisNodeObj = thisMObject();
MFnDependencyNode thisNodeFn( thisNodeObj );
MPlug plg = thisNodeFn.findPlug( inputAttrObj );
MPlugArray connectedPlgs;
if( plg.isConnected() )
{
   if( plg.isSource() ) {
      plg.connectedTo( connectedPlgs, false, true );
   } else if( plg.isDestination() ) {
      plg.connectedTo( connectedPlgs, true, false );
   }
   MFnDependencyNode otherNodeFn( connectedPlgs[0].node() );
   if( otherNodeFn.typeId() == OtherNodeClassName::id )
   {
      otherNodePtr = (OtherNodeClassName*)otherNodeFn.userNode();
   }
}

How to restore GL states in draw() of a custom locator node

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void MyLocator::draw( M3dView&amp;amp; view, ...)
{
   float lastPointSize=0; glGetFloatv( GL_POINT_SIZE, &amp;amp;lastPointSize );
   float lastLineWidth=0; glGetFloatv( GL_LINE_WIDTH, &amp;amp;lastLineWidth );
   bool lightingWasOn = glIsEnabled( GL_LIGHTING ) ? true : false;
   if( lightingWasOn ) { glDisable( GL_LIGHTING ); }
   view.beginGL();
   ...
   view.endGL();
   glPointSize( lastPointSize );
   glLineWidth( lastLineWidth );
   if( lightingWasOn ) { glEnable( GL_LIGHTING ); }
}

How to call compute() of a custom locator without output connection

?
1
2
3
4
5
6
7
void MyLocator::draw( M3dView&amp;amp; view, ...)
{
   MObject thisNodeObj = thisMObject();
   MObject obj = MPlug( thisNodeObj, outputObj ).asMObject();
   ...
}

How to get the normal vector of a current camera

?
1
2
3
4
M3dView view = M3dView::active3dView();
MDagPath camDagPath;
view.getCamera( camDagPath );
MVector cameraZ = MVector(0,0,1) * camDagPath.inclusiveMatrix();

How to create attributes in initialize() of a custom node

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
MStatus MyLocator::initialize()
{
   MRampAttribute      rAttr;
   MFnEnumAttribute    eAttr;
   MFnUnitAttribute    uAttr;
   MFnTypedAttribute   tAttr;
   MFnNumericAttribute nAttr;
   MFnMessageAttribute gAttr;
   timeObj = uAttr.create( "time", "time", MFnUnitAttribute::kTime, 0.0 );
   addAttribute( timeObj );
   angleObj = uAttr.create( "angle", "angle", MFnUnitAttribute::kAngle, 0.0 );
   addAttribute( angleObj );
   boolObj = nAttr.create( "bool", "bool", MFnNumericData::kBoolean, false );
   addAttribute( boolObj );
   intObj = nAttr.create( "int", "int", MFnNumericData::kInt, 0 );
   addAttribute( intObj );
   floatObj = nAttr.create( "float", "float", MFnNumericData::kFloat, 0.f );
   addAttribute( floatObj );
   doubleObj = nAttr.create( "double", "double", MFnNumericData::kDouble, 0.0 );
   addAttribute( doubleObj );
   int2Obj = nAttr.create( "int2", "int2", MFnNumericData::k2Int, 0 );
   addAttribute( int2Obj );
   int3Obj = nAttr.create( "int3", "int3", MFnNumericData::k3Int, 0 );
   addAttribute( int3Obj );
   float2Obj = nAttr.create( "float2", "float2", MFnNumericData::k2Float, 0.f );
   addAttribute( float2Obj );
   float3Obj = nAttr.create( "float3", "float3", MFnNumericData::k3Float, 0.f );
   addAttribute( float3Obj );
   double2Obj = nAttr.create( "double2", "double2", MFnNumericData::k2Double, 0.0 );
   addAttribute( double2Obj );
   double3Obj = nAttr.create( "double3", "double3", MFnNumericData::k3Double, 0.0 );
   addAttribute( double3Obj );
   stringObj = tAttr.create( "string", "string", MFnData::kString, "abc" );
   addAttribute( stringObj );
   matrixObj = tAttr.create( "matrix", "matrix", MFnMatrixAttribute::kDouble );
   addAttribute( matrixObj );
   curveObj = tAttr.create( "curve", "curve", MFnData::kNurbsCurve );
   addAttribute( curveObj );
   meshObj = tAttr.create( "mesh", "mesh", MFnData::kMesh );
   addAttribute( meshObj );
   iaObj = tAttr.create( "iArray", "iArray", MFnData::kIntArray );
   addAttribute( iaObj );
   faObj = tAttr.create( "fArray", "fArray", MFnData::kFloatArray );
   addAttribute( faObj );
   daObj = tAttr.create( "dArray", "dArray", MFnData::kDoubleArray );
   addAttribute( daObj );
   paObj = tAttr.create( "pArray", "pArray", MFnData::kPointArray );
   addAttribute( paObj );
   vaObj = tAttr.create( "vArray", "vArray", MFnData::kVectorArray );
   addAttribute( vaObj );
   saObj = tAttr.create( "sArray", "sArray", MFnData::kStringArray );
   addAttribute( saObj );
   msgObj = gAttr.create( "message", "message" );
   addAttribute( msgObj );
   clrObj = nAttr.createColor( "color", "color" );
   addAttribute( clrObj );
   pntObj = nAttr.createPoint( "point", "point" );
   addAttribute( pntObj );
   enumObj = eAttr.create( "enum", "enum" 0 );
      eAttr.addField( "A", 0 );
      eAttr.addField( "B", 0 );
   addAttribute( enumObj );
   crvRmpObj = rAttr.createCurveRampAttr( "crvRamp", "crvRamp" );
   addAttribute( crvRmpObj );
   clrRmpObj = rAttr.createColorRampAttr( "clrRamp", "clrRamp" );
   addAttribute( clrRmpObj );
   fileNameObj = tAttr.create( "fileName", "fileName", MFnData::kString );
   tAttr.setUsedAsFilename( true );
   addAttribute( fileNameObj );
   ...
}

end,

转载于:https://www.cnblogs.com/yaoyansi/p/5538178.html

[zz]Maya C++ API Programming Tips相关推荐

  1. HyperWorks API Programming for Beginners

    HyperWorks API Programming for Beginners初学者需要掌握的HyperWorks API HyperWorks有两种控制方式:直接通过图形用户界面(GUI)和使用编 ...

  2. iOS封装相册API的tips

    首先几乎每个App都用到了自定义相册的展示,系统在iOS8以后提供了photos.framework来供我们与相册交互.既然要自定义相册,最先要做的就是封装获取相册相关的API.现在已经有很多开源的相 ...

  3. 用maya的api创建自定义的节点Creating Custom Locator

    原文地址 http://www.fevrierdorian.com/blog/post/2010/02/12/Creating-custom-locator-with-Maya-s-Python-AP ...

  4. maya python api,如何使用Maya Python API查找所有上游DG节点?

    I can use hypershade -listUpstreamNodes to get them, but this command is not available in maya batch ...

  5. oracle 修改po税api_[zz]Oracle EBS API: 采购订单承诺日期更改示例

    Oracle EBS API: 采购订单承诺日期更改示例(PO promise date updated with API ) 本示例中, 采用PO模块的API, 实现订单行的送货承诺日期更改.  对 ...

  6. theForger's Win32 API Programming Tutorial

    http://www.winprog.org/tutorial/ 转载于:https://www.cnblogs.com/freeliver54/archive/2012/11/26/2788704. ...

  7. maya api 初接触

    最近在学习maya api相关知识,书和教程看了不少,今天正好来练兵,也算是进入csdn的第一篇博文吧. </pre><p></p><p></p& ...

  8. 使用fetch封装请求_关于如何使用Fetch API执行HTTP请求的实用ES6指南

    使用fetch封装请求 In this guide, I'll show you how to use the Fetch API (ES6+) to perform HTTP requests to ...

  9. maya python教程_Chris Zurbrigg的Maya Python教程合集

    Chris Zurbriggs Patreon的视频更新到2020年年底.在我看来,这些视频在深度和广度以及信息质量上都是无与伦比的.如果可以,请考虑捐赠给Zurbigg. Chris Zurbrig ...

最新文章

  1. Python Qt GUI设计:QTimer计时器类、QThread多线程类和事件处理类(基础篇—8)
  2. 缓存和web缓存分别是什么?
  3. wkhtmltopdf
  4. [地球人]BlogEngine.NET[Appwo.com版]+采集器
  5. jboss eap_HawtIO在JBoss EAP上(第二部分)
  6. 双向链表(不带头结点)
  7. pyqt5的runJavaScript 使用模板
  8. Linux ext3默认块大小,linux – ext3 / ext4物理块大小视图
  9. python第一课教案_Python学习第一课
  10. 周星驰八级全国统一试卷
  11. Atitit 数据库重复数据产生原因与解决总结 目录 1. 原因 1 1.1. 缺少数据约束校验 1 1.2. 表关系关联设计错误 1 2. 约束种类 1 2.1. 分类 表级约束vs列级别约束 2
  12. SQL Server安装下载教程
  13. UCINET软件使用简介——主菜单简介2
  14. python 拼音 四线格_拼音四线三格中的写法示意及书写注意事项
  15. C-V2X灵魂拷问:爆发 | 挑战 | 价值 | 盈利 | 竞合 | 引领
  16. “非著名相声演员”郭德纲【ZZ】
  17. 物联网专业要学c语言吗,物联网应用技术专业是文科还是理科
  18. 帝国源码php安装文件是哪个,帝国CMS数据库配置文件是哪个文件?
  19. 电商时代的逆向思维法则
  20. v.douyin.com/xxx v.ixigua.com/xxx抖音西瓜网址官方生成制作抖音西瓜缩短口令网址(仅供参考学习)

热门文章

  1. C# Replace函数与JS replace函数
  2. MacOS Apple M1 安装ARM架构的JDK及动态切换版本
  3. html5显示字母的值,使用HTML5 Canvas API控制字体的显示与渲染的方法
  4. 德云斗笑社何九华为什么没参加_狗狗的身体卡在了门上,女主人低头一看忍不住笑了:这是膨胀了...
  5. ElasticSearch基本查询一(英文分词)
  6. BIO与NIO、AIO的区别
  7. 2021年信用卡行业发展报告
  8. 2021社区居家养老现状与未来趋势报告
  9. 5G零售行业应用白皮书
  10. 写一函数,将两个字符串连接