electronicarts / dem-bones Goto Github PK
View Code? Open in Web Editor NEWAn automated algorithm to extract the linear blend skinning (LBS) from a set of example poses
Home Page: https://seed.ea.com
License: Other
An automated algorithm to extract the linear blend skinning (LBS) from a set of example poses
Home Page: https://seed.ea.com
License: Other
Thanks sincerely for sharing your code on Github, But I still have a few confusion.
I don't see any code implementing bone joints constraints. I don't know if I missed something or you have not updated it yet.
Any binaries available somewhere? for
Blender
Maya
3dsMax
Hi, Thanks for your code! Really nice work!
I have one question about Best Rigid Transformation from covariance matrix.
From the paper here https://igl.ethz.ch/projects/ARAP/svd_rot.pdf or the SSDR paper
in the function qpT2m:
Eigen::JacobiSVD svd(...)
d(2, 2) = (svd.matrixU()*svd.matrixV.transpose()).determinant();
m.rotMat(k, j) = svd.matrixU()dsvd.matrixV().transpose();
d(2, 2) = (svd.matrixV()*svd.matrixU.transpose()).determinant();
m.rotMat(k, j) = svd.matrixV()dsvd.matrixU().transpose();
===================================
but definitly from the result, your implementation is right. I'm really confused!
Thanks!
Is there a frontend/gui for dembones somewhere available?
I have some .abc
files and the init pose .fbx
.
Do I need to concatenate all the motion sequences into one .abc
file?
or I can use some scripts to decompose multi sequences in the meantime?
Is it possible for Dem-Bones to directly convert a sequence of PLY or OBJ files into a single animated and skinned FBX, instead of using an animated Alembic files?
Hi, I am really confused about the transAffine and transAffineNorm regularizers. I read the original SSDR paper and some following papers like the Robust SSDR in 2014, but can't find the reference for transAffineNorm regularizers.
Would you please tell the reference about the transAffine and transAffineNorm regularizers?
Thanks a lot!
Hi and thanks a lot for this, it works very well !
I was wondering if it could be possible to allow joint scale to better match the deformed geometry. I think, in some cases where scale is supported, it could help reduce the number of bone needed.
Thanks again!
I compile in debug mode in VS2019, Win10. all configures are in debug mode when configure cmake-gui. FBXSDK is debug version lib.
but it seems Alembic from Alembic (from Maya 2020 Update 2 DevKit) only contains release libs. How to get Debug version Alembic? Should I compile Alembic from https://github.com/alembic/alembic? Then how to organize the catalogue? Which version of Alembic (from Maya 2020 Update 2 DevKit) is?
The compile error is:
1>Alembic.lib(DataTypeRegistry.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in AbcReader.obj 1>Alembic.lib(SprImpl.cpp.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in AbcReader.obj 1>Alembic.lib(SprImpl.cpp.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in AbcReader.obj 1>Alembic.lib(AprImpl.cpp.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in AbcReader.obj 1>Alembic.lib(AprImpl.cpp.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in AbcReader.obj 1>Alembic.lib(ScalarPropertyWriter.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in AbcReader.obj 1>Alembic.lib(ScalarPropertyWriter.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in AbcReader.obj 1>Alembic.lib(ArrayPropertyWriter.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in AbcReader.obj 1>Alembic.lib(ArrayPropertyWriter.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in AbcReader.obj 1>Alembic.lib(ArrayPropertyReader.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in AbcReader.obj 1>Alembic.lib(ArrayPropertyReader.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in AbcReader.obj 1>Alembic.lib(ScalarSample.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in AbcReader.obj 1>Alembic.lib(ScalarSample.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in AbcReader.obj 1>AlembicHalf.lib(half.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in AbcReader.obj 1>AlembicHalf.lib(half.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in AbcReader.obj 1>AlembicIex.lib(IexBaseExc.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in AbcReader.obj 1>AlembicIex.lib(IexBaseExc.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MDd_DynamicDebug' in AbcReader.obj 1>LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library 1>D:\Projects\dem-bones\build_debug\Debug\DemBones.exe : fatal error LNK1319: 184 mismatches detected 1>Done building project "DemBonesCmd.vcxproj" -- FAILED. ========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
Occasionally I run in to cases where DemBones gets stuck in an infinite loop while trying to initialize the bones in DemBones.h init(). I've attached a sample fbx and abc that causes the issue.
Any insight as to why?
../bin/DemBones.exe -i="neutral.fbx" -a="face_rom.abc" -b=64 -o="Decomposition_64.fbx"
1 animated mesh sequence(s):
"face_rom.abc" + "neutral.fbx" --> "Decomposition_64.fbx"
Parameters:
nBones (target) = 64
nInitIters = 10 (default)
nIters = 30 (default)
nTransIters = 5 (default)
nWeightsIters = 3 (default)
bindUpdate = 0 (no update) (default)
transAffine = 10 (default)
transAffineNorm = 4 (default)
nnz = 8 (default)
weightsSmooth = 0.0001 (default)
weightsSmoothStep = 1 (default)
Checking ABCs:
"face_rom.abc": /Louise_asym/Louise_asymShape (57 frames)
Reading ABCs......................................................... Done!
Reading FBXs:
"neutral.fbx"... Done!
5034 vertices
Initializing bones: 1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>1>
Hi,
First, I want to say that I'm very impressed with DemBones solution and its possibilities. I'm wondering if it is possible to obtain the output animation of the RIG with changed only the rotation in the joints (translation would be only applied to the root). From the documentation of the parameters, it is not obvious to me how to achieve this. There is a demLock
parameter, but it seems to lock the whole transformation of the joint in the animation.
I just built this recently and BitDefender is flagging the exe as being infected with a virus.
"DemBones.exe is infected with Gen:Variant.Lazy.247481"
please add compute joint scale
Hello,
I am getting the following error messages when I compile demBones in VS2019:
Error: Dem::DemBones: use of class templates requires template argument list
Error C2352 'Dem::DemBones<_Scalar,_AniMeshScalar>::clear': illegal call of non-static member function cmt C:\Users\max\source\repos\cmt\src\DemBones\DemBonesExt.h 108
The line error is in bold text.
DemBonesExt.h
...
/** @brief Clear all data
*/
void clear() {
fTime.resize(0);
boneName.resize(0);
parent.resize(0);
bind.resize(0, 0);
preMulInv.resize(0, 0);
rotOrder.resize(0, 0);
DemBones::clear();
}
Any idea?
Thx,
Max
Hi, I recently used SSDR created a skeleton animation and write the animation into an .fbx file.
Then I tried to use fbxsdk to extract the translation and rotation data of each bone from the animation.
However, I found that the extracted translation or rotation(both Global or Local ) data are always the same as the initial value, but when I import the fbx file into Maya, the animation looks fine, and the local translation and rotation value of each bone varies over time. The data extraction code are shown below:
One thing wierd is that I found the number of AnimStack in the .fbx which created by SSDR are always 2. I'm not sure whether this factor leads to my problem.
bool readFbx(string file_path)
{
FbxManager* Sdkmanager = NULL;
fbxsdk::FbxScene* Scene = NULL;
bool Result;
//prepare the FBX SDK
InitializeSdkObjects(Sdkmanager, Scene);
FbxString file(file_path.c_str());
Result = LoadScene(Sdkmanager, Scene, file.Buffer());
vector<FbxString>boneName;
vector<fbxsdk::FbxNode*>bone_Node;
if (Result == false)
{
FBXSDK_printf("\n\nAn error occurred while loading the scene...");
return Result;
}
else
{
// get the name of each bones of the skeleton
fbxsdk::FbxNode* root = Scene->GetRootNode();
for (int i = 0; i < root->GetChildCount(); ++i)
{
fbxsdk::FbxNode* pNode = root->GetChild(i);
fbxsdk::FbxNodeAttribute::EType lAttributeType;
if (pNode->GetNodeAttribute() == NULL)
{
FBXSDK_printf("NULL Node Attribute\n\n");
}
else
{
lAttributeType = (pNode->GetNodeAttribute()->GetAttributeType());
switch (lAttributeType)
{
case fbxsdk::FbxNodeAttribute::eSkeleton:
GetSkeletonInformation(boneName, bone_Node, pNode);//遍历节点找到mesh节点
break;
case FbxNodeAttribute::eCamera:
break;
default:
break;
}
}
}
// read the global translation data over time
const int AnimStackCount = Scene->GetSrcObjectCount<fbxsdk::FbxAnimStack>();
for (int i = 0; i < AnimStackCount; ++i)
{
fbxsdk::FbxAnimStack* pstack = Scene->GetSrcObject<fbxsdk::FbxAnimStack>(i);
const char* stackname = pstack->GetName();
cout << "Stack: " << stackname << endl;
const int nLayerCount = pstack->GetMemberCount();
for (int j = 0; j < nLayerCount; ++j)
{
fbxsdk::FbxAnimLayer* pLayer = pstack->GetMember<fbxsdk::FbxAnimLayer>(j);
const char* layername = pLayer->GetName();
cout << "Layer: " << layername << endl;
fbxsdk::FbxAnimCurve* lCurveRX = bone_Node[0]->LclRotation.GetCurve(pLayer, FBXSDK_CURVENODE_COMPONENT_X, false);
if (lCurveRX == NULL)
{
continue;
}
int pRXCount = lCurveRX->KeyGetCount();
for (int s = 0; s < pRXCount; ++s)
{
FbxTime ktime = lCurveRX->KeyGetTime(s);
vector<float> bone_position;
for (int bone = 0; bone < bone_Node.size(); ++bone)
{
FbxAMatrix GLOBAL = bone_Node[bone]->EvaluateLocalTransform(ktime);
FbxVector4 T = GLOBAL.GetT();
fbxsdk::FbxString tmpName("LiYuanQian_rig_v001:Root_M");
if (boneName[bone] == tmpName)
{
cout << tmpName.Buffer() << "frame: " << s << " trans:" << T[0] << "," << T[1] << "," << T[2] << "." << " ktime" << endl;;
}
for (int k = 0; k < 3; ++k)
{
bone_position.push_back(T[k]);
}
}
}
}
}
return Result;
}
}
I'm seeing some Imath related compilation issues. Thanks!
dem-bones/include/DemBones/DemBonesExt.h
Line 91 in f46f795
The sample command line program uses the uninitialized model.bindUpdate value as the default value for the argument. Some compilers may not set this to 0 automatically.
I want to know whehter you realize the Bone Transformations Update with joint constraint in your code.
Hi, It's me again!
I met a problem when calculate the gradient ( solveP function) .
when calculate z by solve the linear system A * z = b
some times A is zero matrix-> cause the calculated z is nan.
I am reading the code of convexLS solver, but can't find any reference.
Would you please tell me some reference of the convexLS solver?
Thanks!
In class MyDemBones
of mainCmd.cpp, the member variables tolerance and patience are initialized to (1e-3) and (3).
However, these values are never updated to those passed in via the command line.
It looks like the following lines must be added to the main function to ensure that the user-provided arguments are being respected:
model.tolerance = tolerance.getValue();
model.patience = patience.getValue();
gcc 7.4.0 reports an warning to this line
dem-bones/include/DemBones/DemBones.h
Line 297 in 2ab9b04
Returning reference to temporary triggers segmentation fault or undefined behavior.
Work around is creating an variable.
VectorX x0 = w.col(i).toDense().cwiseMax(0.0);
x=indexing_vector(x0, idx.head(nnzi));
Although it is better to fix not returning temp address in Indexing.h
/home/syoyo/work/dem-bones/include/DemBones/Indexing.h: In instantiation of ‘const typename ArgType::Scalar& Dem::indexing_functor_vector<ArgType, IndexType>::operator()(Eigen::Index) const [with ArgType = Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<double, double>, const Eigen::Matrix<double, -1, 1>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1> > >; IndexType = Eigen::VectorBlock<Eigen::Array<int, -1, 1>, -1>; typename ArgType::Scalar = double; Eigen::Index = long int]’:
/home/syoyo/work/dem-bones/ExtLibs/Eigen/Eigen/src/Core/CoreEvaluators.h:430:110: required from ‘Scalar Eigen::internal::nullary_wrapper<Scalar, NullaryOp, false, true, false>::operator()(const NullaryOp&, IndexType) const [with IndexType = long int; Scalar = double; NullaryOp = Dem::indexing_functor_vector<Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<double, double>, const Eigen::Matrix<double, -1, 1>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1> > >, Eigen::VectorBlock<Eigen::Array<int, -1, 1>, -1> >]’
/home/syoyo/work/dem-bones/ExtLibs/Eigen/Eigen/src/Core/CoreEvaluators.h:533:37: required from ‘Eigen::internal::evaluator<Eigen::CwiseNullaryOp<NullaryOp, PlainObjectType> >::CoeffReturnType Eigen::internal::evaluator<Eigen::CwiseNullaryOp<NullaryOp, PlainObjectType> >::coeff(IndexType) const [with IndexType = long int; NullaryOp = Dem::indexing_functor_vector<Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<double, double>, const Eigen::Matrix<double, -1, 1>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1> > >, Eigen::VectorBlock<Eigen::Array<int, -1, 1>, -1> >; PlainObjectType = Eigen::Matrix<double, -1, 1>; Eigen::internal::evaluator<Eigen::CwiseNullaryOp<NullaryOp, PlainObjectType> >::CoeffReturnType = double]’
/home/syoyo/work/dem-bones/ExtLibs/Eigen/Eigen/src/Core/AssignEvaluator.h:642:5: required from ‘void Eigen::internal::generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>::assignCoeff(Eigen::Index) [with DstEvaluatorTypeT = Eigen::internal::evaluator<Eigen::Matrix<double, -1, 1> >; SrcEvaluatorTypeT = Eigen::internal::evaluator<Eigen::CwiseNullaryOp<Dem::indexing_functor_vector<Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<double, double>, const Eigen::Matrix<double, -1, 1>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1> > >, Eigen::VectorBlock<Eigen::Array<int, -1, 1>, -1> >, Eigen::Matrix<double, -1, 1> > >; Functor = Eigen::internal::assign_op<double, double>; int Version = 0; Eigen::Index = long int]’
/home/syoyo/work/dem-bones/ExtLibs/Eigen/Eigen/src/Core/AssignEvaluator.h:501:7: required from ‘static void Eigen::internal::dense_assignment_loop<Kernel, 1, 0>::run(Kernel&) [with Kernel = Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double, -1, 1> >, Eigen::internal::evaluator<Eigen::CwiseNullaryOp<Dem::indexing_functor_vector<Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<double, double>, const Eigen::Matrix<double, -1, 1>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1> > >, Eigen::VectorBlock<Eigen::Array<int, -1, 1>, -1> >, Eigen::Matrix<double, -1, 1> > >, Eigen::internal::assign_op<double, double>, 0>]’
/home/syoyo/work/dem-bones/ExtLibs/Eigen/Eigen/src/Core/AssignEvaluator.h:767:37: required from ‘void Eigen::internal::call_dense_assignment_loop(DstXprType&, const SrcXprType&, const Functor&) [with DstXprType = Eigen::Matrix<double, -1, 1>; SrcXprType = Eigen::CwiseNullaryOp<Dem::indexing_functor_vector<Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<double, double>, const Eigen::Matrix<double, -1, 1>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1> > >, Eigen::VectorBlock<Eigen::Array<int, -1, 1>, -1> >, Eigen::Matrix<double, -1, 1> >; Functor = Eigen::internal::assign_op<double, double>]’
/home/syoyo/work/dem-bones/ExtLibs/Eigen/Eigen/src/Core/AssignEvaluator.h:926:31: [ skipping 3 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/home/syoyo/work/dem-bones/ExtLibs/Eigen/Eigen/src/Core/AssignEvaluator.h:808:18: required from ‘void Eigen::internal::call_assignment(Dst&, const Src&) [with Dst = Eigen::Matrix<double, -1, 1>; Src = Eigen::CwiseNullaryOp<Dem::indexing_functor_vector<Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<double, double>, const Eigen::Matrix<double, -1, 1>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1> > >, Eigen::VectorBlock<Eigen::Array<int, -1, 1>, -1> >, Eigen::Matrix<double, -1, 1> >]’
/home/syoyo/work/dem-bones/ExtLibs/Eigen/Eigen/src/Core/PlainObjectBase.h:779:32: required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Dem::indexing_functor_vector<Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<double, double>, const Eigen::Matrix<double, -1, 1>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1> > >, Eigen::VectorBlock<Eigen::Array<int, -1, 1>, -1> >, Eigen::Matrix<double, -1, 1> >; Derived = Eigen::Matrix<double, -1, 1>]’
/home/syoyo/work/dem-bones/ExtLibs/Eigen/Eigen/src/Core/Matrix.h:225:24: required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::operator=(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseNullaryOp<Dem::indexing_functor_vector<Eigen::CwiseBinaryOp<Eigen::internal::scalar_max_op<double, double>, const Eigen::Matrix<double, -1, 1>, const Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1> > >, Eigen::VectorBlock<Eigen::Array<int, -1, 1>, -1> >, Eigen::Matrix<double, -1, 1> >; _Scalar = double; int _Rows = -1; int _Cols = 1; int _Options = 0; int _MaxRows = -1; int _MaxCols = 1]’
/home/syoyo/work/dem-bones/include/DemBones/DemBones.h:303:6: required from ‘void Dem::DemBones<_Scalar, _AniMeshScalar>::computeWeights() [with _Scalar = double; _AniMeshScalar = float]’
/home/syoyo/work/dem-bones/include/DemBones/DemBones.h:344:18: required from ‘void Dem::DemBones<_Scalar, _AniMeshScalar>::compute() [with _Scalar = double; _AniMeshScalar = float]’
/home/syoyo/work/dem-bones/src/command/mainCmd.cpp:171:16: required from here
/home/syoyo/work/dem-bones/include/DemBones/Indexing.h:106:30: warning: returning reference to temporary [-Wreturn-local-addr]
return m_arg(m_indices[idx]);
There are finished skin meshes and animations, and then I added some blend shapes.
I added some new bones at the origin without animation, and set lockM to 0 for those new bones. (The original bone is set to 1)
Set the lockW value of the deformation vertex to 0. (set Others to 1)
Set matrix w and matrix m with original data,set w value of new bones to 0, and m value of new bones to Matrix4::Identity().
I want these bones to replace blend shapes,but it did not work. The result of the compute is that these bones are still at the origin, and there are no vertices with their weights.
I don't know how to work properly
mac@Ayushs-MacBook-Pro MacOS % ./dembones -a=a.abc -i=a.fbx -o=out.fbx -b=16
dyld: Library not loaded: /usr/local/opt/llvm/lib/libomp.dylib
Referenced from: /Users/mac/Desktop/dem-bones-1.2.0/bin/MacOS/./dembones
Reason: no suitable image found. Did find:
/usr/local/opt/llvm/lib/libomp.dylib: mach-o, but wrong architecture
/usr/local/opt/llvm/lib/libomp.dylib: mach-o, but wrong architecture
zsh: abort ./dembones -a=a.abc -i=a.fbx -o=out.fbx -b=16
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.