On 06/01/2017 at 14:12, xxxxxxxx wrote:
_<_!--startfragment--_>_
Hi gr4ph0s, thanks for writing us.
I've investigated your question and looking between the HairGuides() and the HairObject() classes I might have found something useful for your needs. I actually suggest you to have a look at the Cinema 4D SDK Hair Generator example which might give you some hints where to look for.
In addition find a short snippet below showing how to create hair from scratch on a generic PolygonObject at its vertices.
At the moment the code is in C++ since on Python it seems there are some issue I still need to address.
Best, Riccardo
if (!doc)
return false;
Int32 hairSegs = 12;
Int32 hairCount = 1000;
// get the selected object
BaseObject* activeObj = doc->GetActiveObject();
if (!activeObj || !activeObj->IsInstanceOf(Opolygon))
return true;
// cast to HairObject
HairObject* hairObj = HairObject::Alloc();
if (!hairObj)
return true;
BaseContainer* hairBC = hairObj->GetDataInstance();
if (hairBC)
{
hairBC->SetLink(HAIRSTYLE_LINK,(C4DAtomGoal* ) activeObj);
hairBC->SetInt32(HAIRSTYLE_HAIR_COUNT, hairCount);
}
// create material
BaseMaterial* hairMat = BaseMaterial::Alloc(Mhair);
doc->InsertMaterial(hairMat);
// create the texture tag and assign to hair object
TextureTag* ttag = TextureTag::Alloc();
ttag->SetMaterial(hairMat);
hairObj->InsertTag(ttag);
// get some information to build the new hair guides
PolygonObject* activePolyObj = ToPoly(activeObj);
const Vector* activePolyPoints = activePolyObj->GetPointR();
const CPolygon* activePolyPolygons = activePolyObj->GetPolygonR();
Int32 activePolyPolygonsCnt = activePolyObj->GetPolygonCount();
Int32 activePolyPointsCnt = activePolyObj->GetPointCount();
// define the hair segs and allocate the guide
HairGuides* customHairGuide = HairGuides::Alloc(activePolyPointsCnt, hairSegs);
if (!customHairGuide)
return false;
// retrieve the pointer to the new guides points
Vector* customHairGuidePoints = customHairGuide->GetPoints();
Int32 customHairGuideGuidePointsCnt = customHairGuide->GetGuidePointCount();
Random rng; rng.Init(SAFEINT32(GeGetMilliSeconds()/1000));
// create a guide at each vertex of the root object
for (Int32 i = 0; i < activePolyPolygonsCnt; i++)
{
CPolygon poly = activePolyPolygons[i];
Int32 vtxCnt = poly.IsTriangle() ? 3 : 4;
for (Int32 k = 0; k < vtxCnt; k++)
{
Vector pos = activePolyPoints[poly.GetPoint(k)];
HairRootData rootData;
rootData.m_ID = poly.GetPoint(k);
rootData.m_Type = HAIR_ROOT_TYPE_VERTEX;
rootData.m_N = CalcFaceNormal(activePolyPoints, poly);
rootData.m_P = pos;
// increase y and add some noise to x and z at each point of the hair guide
for (Int32 j = 0; j < customHairGuideGuidePointsCnt; j++)
{
pos.x += j*2*rng.Get11();
pos.y += j*3;
pos.z += j*2*rng.Get11();
customHairGuidePoints[poly.GetPoint(k) * customHairGuideGuidePointsCnt + j] = pos;
// set the hair root
if (customHairGuide->GetRoot(poly.GetPoint(k)).m_Type == -1)
customHairGuide->SetRoot(poly.GetPoint(k), rootData, false);
}
}
}
// set the new hair guide
hairObj->SetGuides(customHairGuide, false);
// update the hair object
hairObj->Update(doc);
// add the hair object to the scene
doc->InsertObject(hairObj, nullptr, nullptr);
EventAdd();
return true;
_t-->