# Solved Re-performing Hair Edit > Convert from Spline Command?

Hi,

In learning the Hair API, I'm trying to re-perform the `Hair Edit > Convert from Spline` Command.
Basically, you select a spline and it gets converted to a hair object.

My main bottleneck is the `SetGuide` which I believe creates guides in hair object.
`HairObject.SetGuides(guides, clone)`

The problem is the `c4d.modules.hair.HairGuides` doesn't have an initialize command which I need to

1. Define the points
2. Define the position of the guide

Is there a way around this?

Regards,
Ben

hi,

the set guides just define the guide, but you have to create them before.

I've create this more generic example. From this, you should be able to create the guide from the spline.

``````import c4d
from c4d import gui
# Welcome to the world of Python

# Main function
def main():
# Creates the guides
guideCnt = 10
segmentPerGuide = 4
pointsPerGuide = segmentPerGuide +1

guides = c4d.modules.hair.HairGuides(guideCnt, segmentPerGuide)
if guides is None:
raise ValueError("coudln't create the guides")

x = 0
xspace = 10
yspace = 10
# set the points position of the guides.
for guideIndex in range(guideCnt):
# space each guide
x += xspace
for spid in range(pointsPerGuide):
# Calculate the vertical position of each point
pPos = c4d.Vector (x, yspace * spid, 0 )
# get the index of that point in the global guide array
pIndex = guideIndex * pointsPerGuide  + spid
# Sets the point
guides.SetPoint( pIndex, pPos )

# Creates the Hair Object
hairObj = c4d.BaseObject(c4d.Ohair)

# Sets the previously created guide to this hair object.
hairObj.SetGuides(guides, False)

# Inserts the hairObject in the document
doc.InsertObject(hairObj, None, None)

# Inserts an update event in the stack

# Execute main()
if __name__=='__main__':
main()
``````

the convert spline to hair is using the function UniformToNatural to convert bezier curves.
It also take into account any hair tag that could change the render look of the spline.

Cheers,
Manuel

MAXON SDK Specialist

MAXON Registered Developer

@m_magalhaes

Thanks for the response. I was able to create guides but it doesn't seem to follow the original position of the splines.
You can see the problem here:
https://www.dropbox.com/s/g3qw5t7ueyqnlxp/c4d283_recreate_convert_from_spline_hair.mp4?dl=0

Some general notes

1. Spline's position is at world zero, so there's no reason for offset.
2. There seems to be a stray point (i.e. it doesn't follow the original spline's vector position)

Here is the sample file:
https://www.dropbox.com/s/uovawaui1gdz7rs/c4d283_recreate_convert_from_spline_hair.c4d?dl=0

Here is the code so far:

``````import c4d
from c4d import gui

# Main function
def main():
spline = doc.SearchObject("spline")
guide_count = spline.GetSegmentCount()

segment_per_guide = 9
points_per_guide = segment_per_guide
spline_points = spline.GetAllPoints()

guides = c4d.modules.hair.HairGuides(guide_count, segment_per_guide)

for guide_index in range(guide_count):
idx = 0
for spid in range (points_per_guide):
point_index = guide_index * points_per_guide  + spid

if idx <= len(spline_points) - 1:
guides.SetPoint(point_index, spline_points[point_index])
idx += 1
else:
guides.SetPoint(point_index[-1], spline_points[-1]) # This was made to address the stray point but it is still a stray point. lol

hair = c4d.BaseObject(c4d.Ohair)
hair.SetGuides(guides, False)

doc.InsertObject(hair, None, None)

# Execute main()
if __name__=='__main__':
main()
``````

hi,

hair guide are exactly as spline, they have points, segment.
My example was more generic of course and that's why there was an offset on it.
(we try sometimes to create more generic example so we can add them on github later)

look at the following example, it does what you are looking for.

``````import c4d
from c4d import gui
# Welcome to the world of Python

# Main function
def main():
spline = op
if spline is None:
raise ValueError("there's no object selected")
if not spline.IsInstanceOf(c4d.Ospline):
raise ValueError("select a spline")
# we can use a SplineLengthData to use the UniformToNatural function
sld = c4d.utils.SplineLengthData()
# Retrieves the spline matrix
splineMg = spline.GetMg()

segCount = spline.GetSegmentCount()
# number of point in a segment is number of segment +1
segmentPerGuide = 4
pointsPerGuide = segmentPerGuide + 1
# Creates the guides
guides = c4d.modules.hair.HairGuides(segCount, segmentPerGuide)

# for each segment of the spline
for segIndex in range(segCount):
# initialize the splineLenghtData with the current segment
sld.Init(spline, segIndex)
for i in range(pointsPerGuide):
# for each point of the guide, calculate the position for that point
pos = spline.GetSplinePoint(sld.UniformToNatural(i / float(segmentPerGuide) ), segIndex)
# Calculates the points index on the guides points
pointIndex = segIndex * (pointsPerGuide ) + i
# Sets the point position in global space
pos = splineMg * pos
guides.SetPoint( pointIndex, pos )

# Creates the Hair Object
hairObj = c4d.BaseObject(c4d.Ohair)

# Sets the previously created guide to this hair object.
hairObj.SetGuides(guides, False)

# Inserts the hairObject in the document
doc.InsertObject(hairObj, None, None)

# Inserts an update event in the stack

# Execute main()
if __name__=='__main__':
main()
``````

Cheers,
Manuel

MAXON SDK Specialist

MAXON Registered Developer

@m_magalhaes

Thanks! It works as expected.
So that's what you mean by `UniformToNatural`. Basically, even if the segment guides are not the same as spline points, it will conform to its overall shape.